/**
*
*/
package org.springframework.data.aerospike.core;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.aerospike.client.Key;
import com.aerospike.client.Record;
import com.aerospike.client.policy.Policy;
import com.aerospike.client.policy.WritePolicy;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import org.assertj.core.api.Assertions;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.RecoverableDataAccessException;
import org.springframework.data.aerospike.mapping.Document;
import org.springframework.data.aerospike.repository.BaseRepositoriesIntegrationTests;
import org.springframework.data.aerospike.repository.query.Criteria;
import org.springframework.data.aerospike.repository.query.Query;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.annotation.Version;
import com.aerospike.client.AerospikeClient;
import com.aerospike.client.Value;
import com.aerospike.client.query.Filter;
import com.aerospike.client.query.IndexType;
import com.aerospike.helper.query.Qualifier;
import com.aerospike.helper.query.Qualifier.FilterOperation;
/**
*
*
* @author Peter Milne
* @author Jean Mercier
*
*/
public class AerospikeTemplateTests extends BaseRepositoriesIntegrationTests {
@Autowired AerospikeTemplate template;
@Autowired AerospikeClient client;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
cleanDb();
}
private void cleanDb() {
template.delete(Person.class);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
cleanDb();
}
@Test
public void findById_shouldSetVersionEqualToNumberOfModifications() throws Exception {
String id = nextId();
template.insert(new VersionedClass(id, "foobar"));
template.update(new VersionedClass(id, "foobar1"));
template.update(new VersionedClass(id, "foobar2"));
Record raw = client.get(new Policy(), new Key(info.getNamespace(), "versioned-set", id));
Assertions.assertThat(raw.generation).isEqualTo(3);
VersionedClass actual = template.findById(id, VersionedClass.class);
Assertions.assertThat(actual.getVersion()).isEqualTo(3);
}
@Test
public void findById_shouldReturnNullForNonExistingKey() throws Exception {
Person one = template.findById("person-non-existing-key", Person.class);
Assertions.assertThat(one).isNull();
}
@Test
public void find_shouldReturnEmptyResultForQueryWithNoResults() throws Exception {
template.createIndex(Person.class, "Person_age_index", "age",IndexType.NUMERIC );
Query<?> query = new Query<Object>(
Criteria.where("age").is(-10, "age"));
Iterable<Person> it = template.find(query, Person.class);
int count = 0;
for (Person person : it) {
count++;
}
Assertions.assertThat(count).isZero();
}
@Test
public void shouldInsertAndFindWithCustomCollectionSet() throws Exception {
String id = nextId();
CustomCollectionClass initial = new CustomCollectionClass(id, "data0");
template.insert(initial, new WritePolicy());
Record record = client.get(new Policy(), new Key(info.getNamespace(), "custom-set", id));
Assertions.assertThat(record.getString("data")).isEqualTo("data0");
Assertions.assertThat(template.findById(id, CustomCollectionClass.class)).isEqualTo(initial);
}
@Test
public void insertsSimpleEntityCorrectly() {
Person person = new Person("Person-01","Oliver");
person.setAge(25);
template.insert(person);
Person person1 = template.findById("Person-01", Person.class);
assertThat(person1 , is(person));
}
@Test
public void findbyIdFail() {
Person person = new Person("Person-01","Oliver");
person.setAge(25);
template.insert(person);
Person person1 = template.findById("Person", Person.class);
assertNull(person1);
}
@Test (expected = DataIntegrityViolationException.class)
public void throwsExceptionForDuplicateIds() {
Person person = new Person("Person-02","Amol");
person.setAge(28);
template.insert(person);
template.insert(person);
}
@Test (expected = DataIntegrityViolationException.class)
public void rejectsDuplicateIdInInsertAll() {
Person person = new Person("Biff-01", "Amol");
person.setAge(28);
List<Person> records = new ArrayList<Person>();
records.add(person);
records.add(person);
template.insertAll(records);
}
@Test
public void findMultipleFiltersQualifierOnly(){
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",21);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",25);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Qualifier qual1 = new Qualifier("age", FilterOperation.EQ, Value.get(25));
Iterable<Person> it = template.findAllUsingQuery(Person.class, null, qual1);
int count = 0;
Person firstPerson = null;
for (Person person : it){
firstPerson = person;
System.out.print(firstPerson+"\n");
count++;
}
Assert.assertEquals(2, count);
}
@Test
public void findMultipleFiltersFilterAndQualifier(){
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01","John",25);
Person personSven02 = new Person("Sven-02","John",21);
Person personSven03 = new Person("Sven-03","John",24);
Person personSven04 = new Person("Sven-04","WFirstName",25);
Person personSven05 = new Person("Sven-05","ZFirstName",25);
Person personSven06 = new Person("Sven-06","QFirstName",21);
Person personSven07 = new Person("Sven-07","AFirstName",24);
Person personSven08 = new Person("Sven-08","John",25);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
template.insert(personSven05);
template.insert(personSven06);
template.insert(personSven07);
template.insert(personSven08);
Filter filter = Filter.equal("firstName", "John");
Qualifier qual1 = new Qualifier("age", FilterOperation.EQ, Value.get(25));
Iterable<Person> it = template.findAllUsingQuery(Person.class, filter, qual1);
int count = 0;
Person firstPerson = null;
for (Person person : it){
firstPerson = person;
System.out.print(firstPerson+"\n");
count++;
}
Assert.assertEquals(2, count);
}
@SuppressWarnings("rawtypes")
@Test
public void checkIndexingString() {
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",21);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",25);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Query query = new Query(Criteria.where("firstName").is("ALastName","firstName"));
Iterable<Person> it = template.find(query, Person.class);
int count = 0;
Person firstPerson = null;
for (Person person : it){
firstPerson = person;
System.out.print(person+"\n");
count++;
}
Assert.assertEquals(1, count);
Assert.assertEquals(firstPerson, personSven03);
}
@SuppressWarnings("rawtypes")
@Test
public void checkIndexingViaNumeric() {
template.createIndex(Person.class, "Person_age_index", "age",IndexType.NUMERIC );
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",21);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",35);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Query query = new Query(Criteria.where("age").is(35,"age"));
Iterable<Person> it = template.find(query, Person.class);
int count = 0;
Person firstPerson = null;
for (Person person : it){
firstPerson = person;
System.out.print(person+"\n");
count++;
}
Assert.assertEquals(1, count);
Assert.assertEquals(firstPerson, personSven04);
}
@Test (expected = RecoverableDataAccessException.class)
public void testUpdateFailure(){
template.update(new Person("Sven-06","svenfirstName",11));
}
@Test
public void testUpdateSuccess(){
Person person = new Person("Sven-04","WLastName",11);
template.insert(person);
template.update(person);
Person result = template.findById("Sven-04", Person.class);
Assert.assertEquals(result.getAge(), 11);
}
@Test
public void testSimpleDeleteByObject(){
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",21);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",35);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
template.delete(personSven02);
Person result = template.findById("Sven-02", Person.class);
assertNull(result);
}
@Test
public void testSimpleDeleteById(){
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",21);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",35);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
template.delete("Sven-02", Person.class);
Person result = template.findById("Sven-02", Person.class);
assertNull(result);
}
@Test
public void StoreAndRetrieveDate(){
template.createIndex(Person.class, "Person_dateOfBirth_index", "dateOfBirth",IndexType.STRING );
SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
Date birthday1 = null;
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",50);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",25);
try {
birthday1 = formatter.parse("8-Apr-1965");
personSven01.setDateOfBirth(formatter.parse("7-Jun-1903"));
personSven02.setDateOfBirth(birthday1);
personSven03.setDateOfBirth(formatter.parse("7-Jan-1957"));
personSven04.setDateOfBirth(formatter.parse("7-Oct-2000"));
} catch (Exception e) {
// TODO: handle exception
}
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person findDate = template.findById("Sven-02", Person.class);
Assert.assertEquals(findDate.getDateOfBirth(), birthday1);
}
@Test
public void StoreAndRetrieveMap(){
Person personSven01 = new Person("Sven-01","ZLastName",25);
Person personSven02 = new Person("Sven-02","QLastName",50);
Person personSven03 = new Person("Sven-03","ALastName",24);
Person personSven04 = new Person("Sven-04","WLastName",25);
Map<String, String> map = new HashMap<String, String>();
map.put("key", "value");
personSven02.setMap(map);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person findDate = template.findById("Sven-02", Person.class);
Assert.assertEquals(findDate.getMap(), map);
}
@Test
public void StoreAndRetrieveList(){
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
Map<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
personSven02.setMap(map);
ArrayList<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
personSven02.setList(list);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person findDate = template.findById("Sven-02", Person.class);
Assert.assertEquals(findDate.getMap(), map);
Assert.assertEquals(findDate.getList(), list);
}
@Test
public void TestAddToList() {
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
Map<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
personSven02.setMap(map);
ArrayList<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
personSven02.setList(list);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person personWithList = template.findById("Sven-02", Person.class);
personWithList.getList().add("Added something new");
template.update(personWithList);
Person personWithList2 = template.findById("Sven-02", Person.class);
Assert.assertEquals(personWithList2, personWithList);
Assert.assertEquals(personWithList2.getList().size(), 4);
}
@Test
public void TestAddToMap() {
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
Map<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
personSven02.setMap(map);
ArrayList<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
personSven02.setList(list);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person personWithList = template.findById("Sven-02", Person.class);
personWithList.getMap().put("key4","Added something new");
template.update(personWithList);
Person personWithList2 = template.findById("Sven-02", Person.class);
Assert.assertEquals(personWithList2, personWithList);
Assert.assertEquals(personWithList2.getMap().size(), 4);
Assert.assertEquals(personWithList2.getMap().get("key4"), "Added something new");
}
@Test (expected = NullPointerException.class)
public void removingNullIsANoOp() {
template.delete(null);
}
@SuppressWarnings("rawtypes")
@Test
public void countsDocumentsCorrectly() {
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Query query = new Query(Criteria.where("firstName").is("ALastName","firstName"));
int qCount = template.count(query, Person.class);
assertThat(qCount, is(1));
assertThat(template.count(Person.class), is(4L));
}
@Test(expected = IllegalArgumentException.class)
public void countRejectsNullEntityClass() {
template.count(null, (Class<?>) null);
}
@Test(expected = IllegalArgumentException.class)
public void rejectsNullObjectToBeSaved() {
template.save(null);
}
@Test(expected = IllegalArgumentException.class)
public void rejectsNullTypeObjectToBeSaved() {
template.save(null,null);
}
@SuppressWarnings("rawtypes")
@Test
public void executesExistsCorrectly() {
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Query queryExist = new Query(Criteria.where("firstName").is("ALastName","firstName"));
Query queryNotExist = new Query(Criteria.where("firstName").is("Biff","firstName"));
assertThat(template.exists(queryExist, Person.class),is(true));
assertThat(template.exists(queryNotExist, Person.class),is(false));
}
@SuppressWarnings("rawtypes")
@Test
public void updateConsidersMappingAnnotations() {
template.createIndex(Person.class, "Person_firstName_index", "firstName",IndexType.STRING );
Person personSven01 = new Person("Sven-01", "ZLastName", 25);
Person personSven02 = new Person("Sven-02", "QLastName", 50);
Person personSven03 = new Person("Sven-03", "ALastName", 24);
Person personSven04 = new Person("Sven-04", "WLastName", 25);
personSven01.setEmailAddress("old@mail.com");
template.insert(personSven01);
template.insert(personSven02);
template.insert(personSven03);
template.insert(personSven04);
Person personWithMail = template.findById("Sven-01", Person.class);
assertThat(personWithMail.getEmailAddress(), is("old@mail.com"));
personWithMail.setEmailAddress("new@mail.com");
template.update(personWithMail);
Query query = new Query(Criteria.where("firstName").is(personWithMail.getFirstName(),"firstName"));
Iterable<Person> it = template.find(query, Person.class);
int count = 0;
Person firstPerson = null;
for (Person person : it){
firstPerson = person;
System.out.print(person+"\n");
count++;
}
Assert.assertEquals(1, count);
Assert.assertEquals(firstPerson, personWithMail);
assertThat(personWithMail.getEmailAddress(), is("new@mail.com"));
}
@Test
public void shouldAdd() {
String id = nextId();
Person one = Person.builder().id(id).age(25).build();
template.insert(one);
Person updated = template.add(one, "age", 1);
Assertions.assertThat(updated.getAge()).isEqualTo(26);
}
@Test
public void shouldAppend() throws Exception {
String id = nextId();
Person one = Person.builder().id(id).firstName("Nas").build();
template.insert(one);
Person appended = template.append(one, "firstName", "tya");
Assertions.assertThat(appended.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(template.findById(id, Person.class).getFirstName()).isEqualTo("Nastya");
}
@Test
public void shouldAppendMultipleFields() throws Exception {
String id = nextId();
Person one = Person.builder().id(id).firstName("Nas").emailAddress("nastya@").build();
template.insert(one);
Map<String, String> toBeUpdated = new HashMap<>();
toBeUpdated.put("firstName", "tya");
toBeUpdated.put("email", "gmail.com");
Person appended = template.append(one, toBeUpdated);
Assertions.assertThat(appended.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(appended.getEmailAddress()).isEqualTo("nastya@gmail.com");
Person actual = template.findById(id, Person.class);
Assertions.assertThat(actual.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(actual.getEmailAddress()).isEqualTo("nastya@gmail.com");
}
@Test
public void shouldPrepend() throws Exception {
String id = nextId();
Person one = Person.builder().id(id).firstName("tya").build();
template.insert(one);
Person appended = template.prepend(one, "firstName", "Nas");
Assertions.assertThat(appended.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(template.findById(id, Person.class).getFirstName()).isEqualTo("Nastya");
}
@Test
public void shouldPrependMultipleFields() throws Exception {
String id = nextId();
Person one = Person.builder().id(id).firstName("tya").emailAddress("gmail.com").build();
template.insert(one);
Map<String, String> toBeUpdated = new HashMap<>();
toBeUpdated.put("firstName", "Nas");
toBeUpdated.put("email", "nastya@");
Person appended = template.prepend(one, toBeUpdated);
Assertions.assertThat(appended.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(appended.getEmailAddress()).isEqualTo("nastya@gmail.com");
Person actual = template.findById(id, Person.class);
Assertions.assertThat(actual.getFirstName()).isEqualTo("Nastya");
Assertions.assertThat(actual.getEmailAddress()).isEqualTo("nastya@gmail.com");
}
@Getter
@EqualsAndHashCode
@ToString
@Document(collection = "versioned-set")
static class VersionedClass {
@Id
private String id;
@Version
private long version;
private String field;
@PersistenceConstructor
private VersionedClass(String id, String field, long version) {
this.id = id;
this.field = field;
this.version = version;
}
public VersionedClass(String id, String field) {
this.id = id;
this.field = field;
}
}
@Getter
@EqualsAndHashCode
@ToString
@Document(collection = "custom-set")
static class CustomCollectionClass {
@Id
private String id;
private String data;
public CustomCollectionClass(String id, String data) {
this.id = id;
this.data = data;
}
}
}