DATAREDIS-512 - Skip repository index update checks on insert.

We now skip checking for existing index values on insert.

Related tickets: DATAREDIS-504.
Original pull request: #198.
This commit is contained in:
Christoph Strobl
2016-05-18 09:26:40 +02:00
committed by Mark Paluch
parent f732b5f6b9
commit 46f07d7056
5 changed files with 177 additions and 23 deletions

View File

@@ -22,6 +22,7 @@ import static org.mockito.Mockito.*;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import org.junit.Before;
@@ -110,8 +111,8 @@ public class IndexWriterUnitTests {
byte[] indexKey1 = "persons:firstname:rand".getBytes(CHARSET);
byte[] indexKey2 = "persons:firstname:mat".getBytes(CHARSET);
when(connectionMock.keys(any(byte[].class))).thenReturn(
new LinkedHashSet<byte[]>(Arrays.asList(indexKey1, indexKey2)));
when(connectionMock.keys(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList(indexKey1, indexKey2)));
writer.removeKeyFromExistingIndexes(KEY_BIN, new StubIndxedData());
@@ -136,8 +137,8 @@ public class IndexWriterUnitTests {
byte[] indexKey1 = "persons:firstname:rand".getBytes(CHARSET);
byte[] indexKey2 = "persons:firstname:mat".getBytes(CHARSET);
when(connectionMock.keys(any(byte[].class))).thenReturn(
new LinkedHashSet<byte[]>(Arrays.asList(indexKey1, indexKey2)));
when(connectionMock.keys(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList(indexKey1, indexKey2)));
writer.removeAllIndexes(KEYSPACE);
@@ -178,6 +179,42 @@ public class IndexWriterUnitTests {
verify(connectionMock).sAdd(eq(("persons:firstname:" + identityHexString).getBytes(CHARSET)), eq(KEY_BIN));
}
/**
* @see DATAREDIS-512
*/
@Test
public void createIndexShouldNotTryToRemoveExistingValues() {
when(connectionMock.keys(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList("persons:firstname:rand".getBytes(CHARSET))));
writer.createIndexes(KEY_BIN,
Collections.<IndexedData> singleton(new SimpleIndexedPropertyValue(KEYSPACE, "firstname", "Rand")));
verify(connectionMock).sAdd(eq("persons:firstname:Rand".getBytes(CHARSET)), eq(KEY_BIN));
verify(connectionMock).sAdd(eq("persons:key-1:idx".getBytes(CHARSET)),
eq("persons:firstname:Rand".getBytes(CHARSET)));
verify(connectionMock, never()).sRem(any(byte[].class), eq(KEY_BIN));
}
/**
* @see DATAREDIS-512
*/
@Test
public void updateIndexShouldRemoveExistingValues() {
when(connectionMock.keys(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList("persons:firstname:rand".getBytes(CHARSET))));
writer.updateIndexes(KEY_BIN,
Collections.<IndexedData> singleton(new SimpleIndexedPropertyValue(KEYSPACE, "firstname", "Rand")));
verify(connectionMock).sAdd(eq("persons:firstname:Rand".getBytes(CHARSET)), eq(KEY_BIN));
verify(connectionMock).sAdd(eq("persons:key-1:idx".getBytes(CHARSET)),
eq("persons:firstname:Rand".getBytes(CHARSET)));
verify(connectionMock, times(1)).sRem(any(byte[].class), eq(KEY_BIN));
}
static class StubIndxedData implements IndexedData {
@Override

View File

@@ -64,8 +64,8 @@ public class RedisKeyValueAdapterTests {
template = new StringRedisTemplate(connectionFactory);
template.afterPropertiesSet();
RedisMappingContext mappingContext = new RedisMappingContext(new MappingConfiguration(new IndexConfiguration(),
new KeyspaceConfiguration()));
RedisMappingContext mappingContext = new RedisMappingContext(
new MappingConfiguration(new IndexConfiguration(), new KeyspaceConfiguration()));
mappingContext.afterPropertiesSet();
adapter = new RedisKeyValueAdapter(template, mappingContext);
@@ -272,6 +272,45 @@ public class RedisKeyValueAdapterTests {
assertThat(template.opsForSet().members("persons"), not(hasItem("1")));
}
/**
* @see DATAREDIS-512
*/
@Test
public void putWritesIndexDataCorrectly() {
Person rand = new Person();
rand.age = 24;
rand.firstname = "rand";
adapter.put("rand", rand, "persons");
assertThat(template.hasKey("persons:firstname:rand"), is(true));
assertThat(template.hasKey("persons:rand:idx"), is(true));
assertThat(template.opsForSet().isMember("persons:rand:idx", "persons:firstname:rand"), is(true));
Person mat = new Person();
mat.age = 22;
mat.firstname = "mat";
adapter.put("mat", mat, "persons");
assertThat(template.hasKey("persons:firstname:rand"), is(true));
assertThat(template.hasKey("persons:firstname:mat"), is(true));
assertThat(template.hasKey("persons:rand:idx"), is(true));
assertThat(template.hasKey("persons:mat:idx"), is(true));
assertThat(template.opsForSet().isMember("persons:rand:idx", "persons:firstname:rand"), is(true));
assertThat(template.opsForSet().isMember("persons:mat:idx", "persons:firstname:mat"), is(true));
rand.firstname = "frodo";
adapter.put("rand", rand, "persons");
assertThat(template.hasKey("persons:firstname:rand"), is(false));
assertThat(template.hasKey("persons:firstname:mat"), is(true));
assertThat(template.hasKey("persons:firstname:frodo"), is(true));
assertThat(template.hasKey("persons:rand:idx"), is(true));
assertThat(template.opsForSet().isMember("persons:rand:idx", "persons:firstname:frodo"), is(true));
assertThat(template.opsForSet().isMember("persons:mat:idx", "persons:firstname:mat"), is(true));
}
@KeySpace("persons")
static class Person {

View File

@@ -16,9 +16,12 @@
package org.springframework.data.redis.core;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import org.junit.Before;
import org.junit.Test;
@@ -27,11 +30,15 @@ import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.convert.Bucket;
import org.springframework.data.redis.core.convert.RedisData;
import org.springframework.data.redis.core.convert.SimpleIndexedPropertyValue;
/**
* Unit tests for {@link RedisKeyValueAdapter}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
@RunWith(MockitoJUnitRunner.class)
public class RedisKeyValueAdapterUnitTests {
@@ -66,4 +73,40 @@ public class RedisKeyValueAdapterUnitTests {
verify(jedisConnectionFactoryMock, never()).destroy();
}
/**
* @see DATAREDIS-512
*/
@Test
public void putShouldRemoveExistingIndexValuesWhenUpdating() {
RedisData rd = new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("_id", "1")));
rd.addIndexedData(new SimpleIndexedPropertyValue("persons", "firstname", "rand"));
when(redisConnectionMock.keys(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList("persons:firstname:rand".getBytes())));
when(redisConnectionMock.del((byte[][]) anyVararg())).thenReturn(1L);
redisKeyValueAdapter.put("1", rd, "persons");
verify(redisConnectionMock, times(1)).sRem(any(byte[].class), any(byte[].class));
}
/**
* @see DATAREDIS-512
*/
@Test
public void putShouldNotTryToRemoveExistingIndexValuesWhenInsertingNew() {
RedisData rd = new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("_id", "1")));
rd.addIndexedData(new SimpleIndexedPropertyValue("persons", "firstname", "rand"));
when(redisConnectionMock.sMembers(any(byte[].class)))
.thenReturn(new LinkedHashSet<byte[]>(Arrays.asList("persons:firstname:rand".getBytes())));
when(redisConnectionMock.del((byte[][]) anyVararg())).thenReturn(0L);
redisKeyValueAdapter.put("1", rd, "persons");
verify(redisConnectionMock, never()).sRem(any(byte[].class), (byte[][]) anyVararg());
}
}