package me.prettyprint.hector.api.beans;
import static me.prettyprint.hector.api.factory.HFactory.createMutator;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import me.prettyprint.cassandra.serializers.*;
import me.prettyprint.cassandra.service.ColumnSliceIterator;
import me.prettyprint.cassandra.service.template.BaseColumnFamilyTemplateTest;
import me.prettyprint.hector.api.Serializer;
import me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality;
import me.prettyprint.hector.api.factory.HFactory;
import me.prettyprint.hector.api.mutation.Mutator;
import me.prettyprint.hector.api.query.SliceQuery;
import org.junit.After;
import org.junit.Test;
public class DynamicCompositeTest extends BaseColumnFamilyTemplateTest {
private static DynamicCompositeSerializer ds = DynamicCompositeSerializer.get();
private static StringSerializer ss = StringSerializer.get();
private static UUIDSerializer us = UUIDSerializer.get();
private static Serializer<UUID> uss = UUIDSerializer.get();
private static String columnFamily = "DynamicComposite1";
private static String rowKey = "rowKey";
@After
public void after() {
cluster.truncate(keyspace.getKeyspaceName(), columnFamily);
}
@Test
public void allTypesSerialize() {
DynamicComposite composite = new DynamicComposite();
UUID lexUUID = UUID.randomUUID();
com.eaio.uuid.UUID timeUUID = new com.eaio.uuid.UUID();
//add all forward comparators
composite.addComponent(0, "AsciiText", AsciiSerializer.get(), "AsciiType", ComponentEquality.EQUAL);
composite.addComponent(1, new byte[]{0, 1, 2, 3}, BytesArraySerializer.get(), "BytesType", ComponentEquality.EQUAL);
composite.addComponent(2, -1, IntegerSerializer.get(), "IntegerType", ComponentEquality.EQUAL);
composite.addComponent(3, lexUUID, UUIDSerializer.get(), "LexicalUUIDType", ComponentEquality.EQUAL);
composite.addComponent(4, -1l, LongSerializer.get(), "LongType", ComponentEquality.EQUAL);
composite.addComponent(5, timeUUID, TimeUUIDSerializer.get(), "TimeUUIDType", ComponentEquality.EQUAL);
composite.addComponent(6, "UTF8Text", StringSerializer.get(), "UTF8Type", ComponentEquality.EQUAL);
composite.addComponent(7, lexUUID, UUIDSerializer.get(), "UUIDType", ComponentEquality.EQUAL);
//add all reverse comparators
composite.addComponent(8, "AsciiText", AsciiSerializer.get(), "AsciiType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(9, new byte[]{0, 1, 2, 3}, BytesArraySerializer.get(), "BytesType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(10, -1, IntegerSerializer.get(), "IntegerType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(11, lexUUID, UUIDSerializer.get(), "LexicalUUIDType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(12, -1l, LongSerializer.get(), "LongType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(13, timeUUID, TimeUUIDSerializer.get(), "TimeUUIDType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(14, "UTF8Text", StringSerializer.get(), "UTF8Type(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(15, lexUUID, UUIDSerializer.get(), "UUIDType(reversed=true)", ComponentEquality.EQUAL);
composite.addComponent(16, "My element", ComponentEquality.EQUAL);
//serialize to the native bytes value
ByteBuffer buffer = DynamicCompositeSerializer.get().toByteBuffer(composite);
//now deserialize and ensure the values are the same
DynamicComposite parsed = DynamicCompositeSerializer.get().fromByteBuffer(buffer);
assertEquals("AsciiText", parsed.get(0, AsciiSerializer.get()));
assertArrayEquals(new byte[]{0, 1, 2, 3}, parsed.get(1, BytesArraySerializer.get()));
assertEquals(Integer.valueOf(-1), parsed.get(2, IntegerSerializer.get()));
assertEquals(lexUUID, parsed.get(3, UUIDSerializer.get()));
assertEquals(Long.valueOf(-1l), parsed.get(4, LongSerializer.get()));
assertEquals(timeUUID, parsed.get(5, TimeUUIDSerializer.get()));
assertEquals("UTF8Text", parsed.get(6, StringSerializer.get()));
assertEquals(lexUUID, parsed.get(7, UUIDSerializer.get()));
//now test all the reversed values
assertEquals("AsciiText", parsed.get(8, AsciiSerializer.get()));
assertArrayEquals(new byte[]{0, 1, 2, 3}, parsed.get(9, BytesArraySerializer.get()));
assertEquals(Integer.valueOf(-1), parsed.get(10, IntegerSerializer.get()));
assertEquals(lexUUID, parsed.get(11, UUIDSerializer.get()));
assertEquals(Long.valueOf(-1l), parsed.get(12, LongSerializer.get()));
assertEquals(timeUUID, parsed.get(13, TimeUUIDSerializer.get()));
assertEquals("UTF8Text", parsed.get(14, StringSerializer.get()));
assertEquals(lexUUID, parsed.get(15, UUIDSerializer.get()));
assertEquals("My element", parsed.get(16, StringSerializer.get()));
}
@Test
public void testUUIDGetAll() {
// Gets all columns in the row regardless of the column name
init();
// Get all rows
Set<UUID> results = new HashSet<UUID>();
ColumnSliceIterator<String, DynamicComposite, String> iterator = getIterator(rowKey, null, null);
while(iterator.hasNext()) {
HColumn<DynamicComposite, String> column = iterator.next();
DynamicComposite composite = column.getName();
UUID component1 = composite.get(1, us);
results.add(component1);
}
assertEquals("Failed to retrieve all columns", 8, results.size());
}
@Test
public void testUUIDGetSlice() {
// Gets all columns based on the first component in the column name
Map<UUID, Set<UUID>> ids = init();
for(Entry<UUID, Set<UUID>> entry : ids.entrySet()) {
UUID component0 = entry.getKey();
// start at first column who's single component == component0
DynamicComposite start = new DynamicComposite();
start.addComponent(component0, us);
// up to and including any column whose first component == component0 regardless of remaining component values
DynamicComposite end = new DynamicComposite();
end.addComponent(component0, us, us.getComparatorType().getTypeName(), ComponentEquality.GREATER_THAN_EQUAL);
ColumnSliceIterator<String, DynamicComposite, String> iterator = getIterator(rowKey, start, end);
while(iterator.hasNext()) {
HColumn<DynamicComposite, String> column = iterator.next();
DynamicComposite composite = column.getName();
assertEquals(component0, composite.get(0, us));
assertTrue(ids.get(component0).contains(composite.get(1, us)));
}
}
}
@Test
public void testStringGetSlice() {
Mutator<String> mutator = createMutator(keyspace, ss);
DynamicComposite composite = (DynamicComposite) new DynamicComposite().
addComponent("a", ss).
addComponent("ba", ss).
addComponent("ca", ss).
addComponent("da", ss);
mutator.addInsertion(rowKey, columnFamily, HFactory.createColumn(composite, composite.toString(), ds, ss));
composite = (DynamicComposite) new DynamicComposite().
addComponent("a", ss).
addComponent("bb", ss).
addComponent("cb", ss).
addComponent("db", ss);
mutator.addInsertion(rowKey, columnFamily, HFactory.createColumn(composite, composite.toString(), ds, ss));
composite = (DynamicComposite) new DynamicComposite().
addComponent("b", ss).
addComponent("ba", ss).
addComponent("ca", ss).
addComponent("da", ss);
mutator.addInsertion(rowKey, columnFamily, HFactory.createColumn(composite, composite.toString(), ds, ss));
composite = (DynamicComposite) new DynamicComposite().
addComponent("b", ss).
addComponent("bb", ss).
addComponent("cb", ss).
addComponent("db", ss);
mutator.addInsertion(rowKey, columnFamily, HFactory.createColumn(composite, composite.toString(), ds, ss));
mutator.execute();
String compType = ss.getComparatorType().getTypeName();
System.out.println("LESS_THAN_EQUAL");
DynamicComposite end = (DynamicComposite) new DynamicComposite().
addComponent("b", ss, compType).
addComponent("ba", ss).
addComponent("ca", ss).
addComponent("da", ss, compType, ComponentEquality.LESS_THAN_EQUAL); // s@a:s@ba:s@ca:s@da thru s@a:s@bb:s@cb:s@db
ColumnSliceIterator<String, DynamicComposite, String> iterator = getIterator(rowKey, null, end);
while(iterator.hasNext()) {
System.out.println(iterator.next().getName());
}
System.out.println("EQUAL");
end = (DynamicComposite) new DynamicComposite().
addComponent("b", ss, compType).
addComponent("ba", ss).
addComponent("ca", ss).
addComponent("da", ss, compType, ComponentEquality.EQUAL); // s@a:s@ba:s@ca:s@da thru s@b:s@ba:s@ca:s@da
iterator = getIterator(rowKey, null, end);
while(iterator.hasNext()) {
System.out.println(iterator.next().getName());
}
System.out.println("GREATER_THAN_EQUAL");
end = (DynamicComposite) new DynamicComposite().
addComponent("b", ss, compType).
addComponent("bb", ss, compType, ComponentEquality.GREATER_THAN_EQUAL); // s@a:s@ba:s@ca:s@da thru s@b:s@bb:s@cb:s@db
iterator = getIterator(rowKey, null, end);
while(iterator.hasNext()) {
System.out.println(iterator.next().getName());
}
}
private ColumnSliceIterator<String, DynamicComposite, String> getIterator(String key, DynamicComposite start, DynamicComposite end) {
SliceQuery<String, DynamicComposite, String> query = HFactory.createSliceQuery(keyspace, ss, ds, ss).
setColumnFamily(columnFamily).
setKey(key);
return new ColumnSliceIterator<String, DynamicComposite, String>(query, start, end, false);
}
/**
* Initializes a row whose DynamicComposite column name components are two UUIDs.
* Sample row:
*
* RowKey: ROW_KEY
* => (column=u@77df3aa8-f8b2-4658-be4d-ad9401f4388a:u@222c532f-e310-4803-8119-3a96f770b763, value=[77df3aa8-f8b2-4658-be4d-ad9401f4388a, 222c532f-e310-4803-8119-3a96f770b763], timestamp=1353028069149000)
* => (column=u@77df3aa8-f8b2-4658-be4d-ad9401f4388a:u@acf45bbe-4b2d-4f90-80d3-3b2288ccb13a, value=[77df3aa8-f8b2-4658-be4d-ad9401f4388a, acf45bbe-4b2d-4f90-80d3-3b2288ccb13a], timestamp=1353028069149002)
* => (column=u@77df3aa8-f8b2-4658-be4d-ad9401f4388a:u@b1015157-e030-45dd-b5a3-67a11f7e6350, value=[77df3aa8-f8b2-4658-be4d-ad9401f4388a, b1015157-e030-45dd-b5a3-67a11f7e6350], timestamp=1353028069138000)
* => (column=u@77df3aa8-f8b2-4658-be4d-ad9401f4388a:u@f42dc238-7fab-48ec-b831-632bd1adaad9, value=[77df3aa8-f8b2-4658-be4d-ad9401f4388a, f42dc238-7fab-48ec-b831-632bd1adaad9], timestamp=1353028069149001)
* => (column=u@def2ce2c-a77d-48de-8072-1b5c06fb0e07:u@20624858-77fb-495b-9886-12b7ff230da9, value=[def2ce2c-a77d-48de-8072-1b5c06fb0e07, 20624858-77fb-495b-9886-12b7ff230da9], timestamp=1353028069150002)
* => (column=u@def2ce2c-a77d-48de-8072-1b5c06fb0e07:u@bff9acb8-2b61-420a-b6ad-4095bc87f32c, value=[def2ce2c-a77d-48de-8072-1b5c06fb0e07, bff9acb8-2b61-420a-b6ad-4095bc87f32c], timestamp=1353028069150001)
* => (column=u@def2ce2c-a77d-48de-8072-1b5c06fb0e07:u@c9b0bfc4-b756-43f8-bcd9-1ec6680b4bde, value=[def2ce2c-a77d-48de-8072-1b5c06fb0e07, c9b0bfc4-b756-43f8-bcd9-1ec6680b4bde], timestamp=1353028069150003)
* => (column=u@def2ce2c-a77d-48de-8072-1b5c06fb0e07:u@decaf265-1213-42e8-a489-a991d4d00d97, value=[def2ce2c-a77d-48de-8072-1b5c06fb0e07, decaf265-1213-42e8-a489-a991d4d00d97], timestamp=1353028069150000)
*
* @return Map of first component to a set of the corresponding second components
*/
private Map<UUID, Set<UUID>> init() {
Mutator<String> mutator = createMutator(keyspace, ss);
Map<UUID, Set<UUID>> ids = new HashMap<UUID, Set<UUID>>();
ids.put(UUID.randomUUID(), new HashSet<UUID>());
ids.put(UUID.randomUUID(), new HashSet<UUID>());
for(Entry<UUID, Set<UUID>> entry : ids.entrySet()) {
for(int i = 0; i < 4; i++) {
UUID uuid = UUID.randomUUID();
DynamicComposite composite = (DynamicComposite) new DynamicComposite().addComponent(entry.getKey(), uss).addComponent(uuid, uss);
mutator.addInsertion(rowKey, columnFamily, HFactory.createColumn(composite, composite.toString(), ds, ss));
entry.getValue().add(uuid);
}
}
mutator.execute();
return ids;
}
}