@@ -27,20 +27,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import com.couchbase.client.core.error.TimeoutException;
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
import com.couchbase.client.core.retry.RetryReason;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.core.ExecutableFindByIdOperation.ExecutableFindById;
|
||||
import org.springframework.data.couchbase.core.ExecutableRemoveByIdOperation.ExecutableRemoveById;
|
||||
@@ -460,6 +456,583 @@ class CouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationTests {
|
||||
.one(modified.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsert(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withUpsertPaths("roles").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
mutableUser.setVersion(999);
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withCasProvided().withUpsertPaths("roles").one(mutableUser));
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
couchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withCasProvided().withUpsertPaths("roles").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withUpsertPaths("roles", "address.street").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY).withUpsertPaths("roles", "address.street").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1)).withUpsertPaths("roles", "address.street").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplace(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("firstname").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setVersion(999);
|
||||
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withReplacePaths("firstname").one(mutableUser));
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withReplacePaths("firstname").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("firstname", "address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY).withReplacePaths("firstname", "address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
user.setAddress(address);
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1)).withReplacePaths("firstname", "address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("roles", "address.city").one(mutableUser));
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsert(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withInsertPaths("roles").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertNotEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
mutableUser.setVersion(999);
|
||||
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withInsertPaths("roles").one(mutableUser));
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withInsertPaths("roles").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withInsertPaths("roles", "address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withInsertPaths("address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withInsertPaths("address.city").one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class).withInsertPaths("firstname").one(mutableUser));
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemove(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
assertNotNull(user.getRoles());
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withRemovePaths("roles").one(user);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertNull(user.getRoles());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
String userId = user.getId();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "otherlast");
|
||||
mutableUser.setVersion(999);
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withRemovePaths("roles").one(mutableUser));
|
||||
|
||||
// success on correct cas
|
||||
user.setVersion(user.getVersion());
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withRemovePaths("roles").one(user);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(userId);
|
||||
|
||||
assertNull(user.getRoles());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
user.setAddress(mutableAddress);
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withRemovePaths("roles", "address.city").one(user);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertNull(user.getRoles());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withRemovePaths("lastname").one(user);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertNull(user.getLastname());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withRemovePaths("lastname").one(user);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
assertNull(user.getLastname());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class, ()-> couchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withRemovePaths("roles").one(mutableUser));
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdChained(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = couchbaseTemplate.insertById(MutableUser.class).one(user);
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mAddress = new Address();
|
||||
mAddress.setCity("othercity");
|
||||
mAddress.setStreet("otherstreet");
|
||||
mutableUser.setAddress(mAddress);
|
||||
mutableUser.setSubuser(new MutableUser("subuser", "subfirstname", "sublastname"));
|
||||
|
||||
couchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withInsertPaths("roles", "subuser.firstname")
|
||||
.withRemovePaths("address.city")
|
||||
.withUpsertPaths("firstname")
|
||||
.withReplacePaths("address.street")
|
||||
.one(mutableUser);
|
||||
|
||||
user = couchbaseTemplate.findById(MutableUser.class).one(user.getId());
|
||||
|
||||
assertNull(user.getAddress().getCity());
|
||||
assertEquals(mAddress.getStreet(), user.getAddress().getStreet());
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(mutableUser.getSubuser().getFirstname(), user.getSubuser().getFirstname());
|
||||
assertNull(user.getSubuser().getLastname());
|
||||
} finally {
|
||||
couchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertById() {
|
||||
|
||||
@@ -28,20 +28,17 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import com.couchbase.client.core.error.TimeoutException;
|
||||
import com.couchbase.client.core.msg.kv.DurabilityLevel;
|
||||
import com.couchbase.client.core.retry.RetryReason;
|
||||
import com.couchbase.client.java.query.QueryScanConsistency;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.dao.OptimisticLockingFailureException;
|
||||
import org.springframework.data.couchbase.core.ReactiveFindByIdOperation.ReactiveFindById;
|
||||
import org.springframework.data.couchbase.core.ReactiveRemoveByIdOperation.ReactiveRemoveById;
|
||||
@@ -341,6 +338,592 @@ class ReactiveCouchbaseTemplateKeyValueIntegrationTests extends JavaIntegrationT
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsert(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withUpsertPaths("roles").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
mutableUser.setVersion(999);
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withCasProvided().withUpsertPaths("roles").one(mutableUser).block());
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withCasProvided().withUpsertPaths("roles").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withUpsertPaths("roles", "address.street").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withUpsertPaths("roles", "address.street").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdUpsertMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
mutableUser.setAddress(address);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withUpsertPaths("roles", "address.street").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getRoles(), mutableUser.getRoles());
|
||||
assertEquals(user.getAddress().getStreet(), mutableUser.getAddress().getStreet());
|
||||
assertNull(user.getAddress().getCity());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplace(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("firstname").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setVersion(999);
|
||||
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withReplacePaths("firstname").one(mutableUser).block());
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withReplacePaths("firstname").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("firstname", "address.city")
|
||||
.one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withReplacePaths("firstname", "address.city").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
user.setAddress(address);
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withReplacePaths("firstname", "address.city").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdReplaceMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class,
|
||||
()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withReplacePaths("roles", "address.city")
|
||||
.one(mutableUser).block());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsert(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withInsertPaths("roles").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertNotEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
mutableUser.setVersion(999);
|
||||
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withInsertPaths("roles").one(mutableUser).block());
|
||||
|
||||
// success on correct cas
|
||||
mutableUser.setVersion(user.getVersion());
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withInsertPaths("roles").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withInsertPaths("roles", "address.city").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withInsertPaths("address.city").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
mutableUser.setAddress(mutableAddress);
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withInsertPaths("address.city").one(mutableUser).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertEquals(user.getAddress().getCity(), mutableUser.getAddress().getCity());
|
||||
assertNull(user.getAddress().getStreet());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdInsertMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withInsertPaths("firstname").one(mutableUser).block());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemove(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
assertNotNull(user.getRoles());
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withRemovePaths("roles").one(user).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertNull(user.getRoles());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveWithCAS(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
String userId = user.getId();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "otherlast");
|
||||
mutableUser.setVersion(999);
|
||||
// if case is incorrect then exception is thrown
|
||||
assertThrows(OptimisticLockingFailureException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided()
|
||||
.withRemovePaths("roles").one(mutableUser).block());
|
||||
|
||||
// success on correct cas
|
||||
user.setVersion(user.getVersion());
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withCasProvided().withRemovePaths("roles").one(user).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(userId).block();
|
||||
|
||||
assertNull(user.getRoles());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultiple() {
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mutableAddress = new Address();
|
||||
mutableAddress.setCity("othercity");
|
||||
mutableAddress.setStreet("street");
|
||||
user.setAddress(mutableAddress);
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withRemovePaths("roles", "address.city").one(user).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertNull(user.getRoles());
|
||||
assertNull(user.getAddress().getCity());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultipleWithDurability(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withDurability(DurabilityLevel.MAJORITY)
|
||||
.withRemovePaths("lastname").one(user).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertNull(user.getLastname());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMultipleWithExpiry(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class).withExpiry(Duration.ofSeconds(1))
|
||||
.withRemovePaths("lastname").one(user).block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
assertNull(user.getLastname());
|
||||
|
||||
// user should be gone
|
||||
int tries = 0;
|
||||
MutableUser foundUser;
|
||||
do {
|
||||
sleepSecs(2);
|
||||
foundUser = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
} while (tries++ < 5 && foundUser != null);
|
||||
assertNull(foundUser);
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdRemoveMissingPath(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
|
||||
assertThrows(InvalidDataAccessResourceUsageException.class, ()-> reactiveCouchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withRemovePaths("roles").one(mutableUser).block());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutateInByIdChained(){
|
||||
try {
|
||||
MutableUser user = new MutableUser(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
Address address = new Address();
|
||||
address.setCity("city");
|
||||
address.setStreet("street");
|
||||
user.setAddress(address);
|
||||
user = reactiveCouchbaseTemplate.insertById(MutableUser.class).one(user).block();
|
||||
|
||||
MutableUser mutableUser = new MutableUser(user.getId(), "othername", "");
|
||||
mutableUser.setRoles(Collections.singletonList("ADMIN"));
|
||||
Address mAddress = new Address();
|
||||
mAddress.setCity("othercity");
|
||||
mAddress.setStreet("otherstreet");
|
||||
mutableUser.setAddress(mAddress);
|
||||
mutableUser.setSubuser(new MutableUser("subuser", "subfirstname", "sublastname"));
|
||||
|
||||
reactiveCouchbaseTemplate.mutateInById(MutableUser.class)
|
||||
.withInsertPaths("roles", "subuser.firstname")
|
||||
.withRemovePaths("address.city")
|
||||
.withUpsertPaths("firstname")
|
||||
.withReplacePaths("address.street")
|
||||
.one(mutableUser)
|
||||
.block();
|
||||
|
||||
user = reactiveCouchbaseTemplate.findById(MutableUser.class).one(user.getId()).block();
|
||||
|
||||
assertNull(user.getAddress().getCity());
|
||||
assertEquals(mAddress.getStreet(), user.getAddress().getStreet());
|
||||
assertEquals(mutableUser.getRoles(), user.getRoles());
|
||||
assertEquals(mutableUser.getFirstname(), user.getFirstname());
|
||||
assertEquals(mutableUser.getSubuser().getFirstname(), user.getSubuser().getFirstname());
|
||||
assertNull(user.getSubuser().getLastname());
|
||||
} finally {
|
||||
reactiveCouchbaseTemplate.removeByQuery(MutableUser.class).withConsistency(QueryScanConsistency.REQUEST_PLUS).all();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertById() {
|
||||
User user = new User(UUID.randomUUID().toString(), "firstname", "lastname");
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.springframework.data.couchbase.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Document
|
||||
public class MutableUser extends User{
|
||||
public MutableUser(String id, String firstname, String lastname) {
|
||||
super(id, firstname, lastname);
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Address address;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private MutableUser subuser;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private List<String> roles;
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user