Added a timeout to the map module
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/MapManager.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/MapManager.java
index e6d8125..62fe57d 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/MapManager.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/MapManager.java
@@ -38,6 +38,14 @@
*/
public void putString( final String key, final String value );
+ /**
+ * The time to live (in seconds) of the string
+ * @param key
+ * @param value
+ * @param ttl
+ */
+ public void putString( final String key, final String value, final int ttl );
+
/**
* Return the uuid, null if not found
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java
index e582e55..c077c7d 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapManagerImpl.java
@@ -57,6 +57,12 @@
@Override
+ public void putString( final String key, final String value, final int ttl ) {
+ mapSerialization.putString( scope, key, value, ttl );
+ }
+
+
+ @Override
public UUID getUuid( final String key ) {
return mapSerialization.getUuid(scope,key);
}
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
index 33f2043..6e7e328 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerialization.java
@@ -18,6 +18,8 @@
*/
package org.apache.usergrid.persistence.map.impl;
+
+
import java.util.UUID;
import org.apache.usergrid.persistence.core.migration.schema.Migration;
@@ -33,32 +35,38 @@
/**
* Return the string, null if not found
*/
- public void putString(final MapScope scope, final String key, final String value );
+ public void putString( final MapScope scope, final String key, final String value );
+
+ /**
+ * Write the string
+ */
+ public void putString( final MapScope scope, final String key, final String value, final int ttl );
/**
* Return the uuid, null if not found
*/
- public UUID getUuid(final MapScope scope, final String key );
+ public UUID getUuid( final MapScope scope, final String key );
/**
* Return the uuid, null if not found
*/
- public void putUuid(final MapScope scope, final String key, final UUID putUuid );
+ public void putUuid( final MapScope scope, final String key, final UUID putUuid );
/**
* Return the long, null if not found
*/
- public Long getLong(final MapScope scope, final String key );
+ public Long getLong( final MapScope scope, final String key );
/**
* Return the long, null if not found
*/
- public void putLong(final MapScope scope, final String key, final Long value );
+ public void putLong( final MapScope scope, final String key, final Long value );
/**
* Delete the key
*
* @param key The key used to delete the entry
*/
- public void delete(final MapScope scope, final String key );}
+ public void delete( final MapScope scope, final String key );
+}
diff --git a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerializationImpl.java b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerializationImpl.java
index 1b38d3c..d3bd3c5 100644
--- a/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerializationImpl.java
+++ b/stack/corepersistence/map/src/main/java/org/apache/usergrid/persistence/map/impl/MapSerializationImpl.java
@@ -42,6 +42,7 @@
import com.google.common.hash.PrimitiveSink;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.netflix.astyanax.ColumnListMutation;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.MutationBatch;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
@@ -126,33 +127,85 @@
@Override
public void putString( final MapScope scope, final String key, final String value ) {
- Preconditions.checkNotNull(scope, "mapscope is required");
+ final RowOp op = new RowOp() {
+ @Override
+ public void rowOp( final ScopedRowKey<MapEntryKey> scopedRowKey,
+ final ColumnListMutation<Boolean> columnListMutation ) {
+ columnListMutation.putColumn( true, value );
+ }
+ };
+
+
+ writeString( scope, key, value, op );
+ }
+
+
+ @Override
+ public void putString( final MapScope scope, final String key, final String value, final int ttl ) {
+ Preconditions.checkArgument( ttl > 0, "ttl must be > than 0" );
+
+ final RowOp op = new RowOp() {
+ @Override
+ public void rowOp( final ScopedRowKey<MapEntryKey> scopedRowKey,
+ final ColumnListMutation<Boolean> columnListMutation ) {
+ columnListMutation.putColumn( true, value, ttl );
+ }
+ };
+
+
+ writeString( scope, key, value, op );
+ }
+
+
+ /**
+ * Write our string index with the specified row op
+ * @param scope
+ * @param key
+ * @param value
+ * @param rowOp
+ */
+ private void writeString( final MapScope scope, final String key, final String value, final RowOp rowOp ) {
+
+ Preconditions.checkNotNull( scope, "mapscope is required" );
Preconditions.checkNotNull( key, "key is required" );
Preconditions.checkNotNull( value, "value is required" );
final MutationBatch batch = keyspace.prepareMutationBatch();
//add it to the entry
- final ScopedRowKey<MapEntryKey> entryRowKey = MapEntryKey.fromKey(scope, key);
+ final ScopedRowKey<MapEntryKey> entryRowKey = MapEntryKey.fromKey( scope, key );
- //serialize to the entry
- batch.withRow(MAP_ENTRIES, entryRowKey).putColumn(true, value);
+ //serialize to the
+ // entry
+
+
+ rowOp.rowOp( entryRowKey, batch.withRow( MAP_ENTRIES, entryRowKey ) );
+
//add it to the keys
final int bucket = BUCKET_LOCATOR.getCurrentBucket( key );
- final BucketScopedRowKey< String> keyRowKey =
- BucketScopedRowKey.fromKey( scope.getApplication(), key, bucket);
+ final BucketScopedRowKey<String> keyRowKey = BucketScopedRowKey.fromKey( scope.getApplication(), key, bucket );
//serialize to the entry
- batch.withRow(MAP_KEYS, keyRowKey).putColumn(key, true);
+ batch.withRow( MAP_KEYS, keyRowKey ).putColumn( key, true );
- executeBatch(batch);
+
+ executeBatch( batch );
}
+ private static interface RowOp{
+
+ /**
+ * Callback to do the row
+ * @param scopedRowKey The row key
+ * @param columnListMutation The column mutation
+ */
+ void rowOp(final ScopedRowKey<MapEntryKey> scopedRowKey, final ColumnListMutation<Boolean> columnListMutation);
+ }
@Override
public UUID getUuid( final MapScope scope, final String key ) {
@@ -255,18 +308,18 @@
@Override
public Collection<MultiTennantColumnFamilyDefinition> getColumnFamilies() {
- final MultiTennantColumnFamilyDefinition mapEntries =
+ final MultiTennantColumnFamilyDefinition mapEntries =
new MultiTennantColumnFamilyDefinition( MAP_ENTRIES,
- BytesType.class.getSimpleName(),
- BytesType.class.getSimpleName(),
- BytesType.class.getSimpleName(),
+ BytesType.class.getSimpleName(),
+ BytesType.class.getSimpleName(),
+ BytesType.class.getSimpleName(),
MultiTennantColumnFamilyDefinition.CacheOption.KEYS );
- final MultiTennantColumnFamilyDefinition mapKeys =
+ final MultiTennantColumnFamilyDefinition mapKeys =
new MultiTennantColumnFamilyDefinition( MAP_KEYS,
- BytesType.class.getSimpleName(),
- UTF8Type.class.getSimpleName(),
- BytesType.class.getSimpleName(),
+ BytesType.class.getSimpleName(),
+ UTF8Type.class.getSimpleName(),
+ BytesType.class.getSimpleName(),
MultiTennantColumnFamilyDefinition.CacheOption.KEYS );
return Arrays.asList( mapEntries, mapKeys );
diff --git a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/MapManagerTest.java b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/MapManagerTest.java
index 28000fe..df4394e 100644
--- a/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/MapManagerTest.java
+++ b/stack/corepersistence/map/src/test/java/org/apache/usergrid/persistence/map/MapManagerTest.java
@@ -20,7 +20,9 @@
package org.apache.usergrid.persistence.map;
-import org.apache.usergrid.persistence.core.test.UseModules;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -28,14 +30,13 @@
import org.apache.usergrid.persistence.core.guice.MigrationManagerRule;
import org.apache.usergrid.persistence.core.test.ITRunner;
+import org.apache.usergrid.persistence.core.test.UseModules;
import org.apache.usergrid.persistence.map.guice.TestMapModule;
import org.apache.usergrid.persistence.map.impl.MapScopeImpl;
import org.apache.usergrid.persistence.model.entity.SimpleId;
import com.google.inject.Inject;
-import java.util.UUID;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@@ -76,6 +77,40 @@
assertEquals( value, returned );
}
+
+ @Test
+ public void writeReadStringTTL() throws InterruptedException {
+
+ MapManager mm = mmf.createMapManager( this.scope );
+
+ final String key = "key";
+ final String value = "value";
+ final int ttl = 5;
+
+
+ mm.putString( key, value, ttl );
+
+ final long startTime = System.currentTimeMillis();
+
+ final String returned = mm.getString( key );
+
+ assertEquals( value, returned );
+
+ final long endTime = startTime + TimeUnit.SECONDS.toMillis( ttl + 1 );
+
+ final long remaining = endTime - System.currentTimeMillis();
+
+ //now sleep and assert it gets removed
+ Thread.sleep( remaining );
+
+ //now read it should be gone
+ final String timedOut = mm.getString( key );
+
+ assertNull("Value was not returned", timedOut);
+
+ }
+
+
@Test
public void writeReadUUID() {
MapManager mm = mmf.createMapManager( this.scope );
@@ -90,6 +125,7 @@
assertEquals( value, returned );
}
+
@Test
public void writeReadLong() {
MapManager mm = mmf.createMapManager( this.scope );
@@ -143,6 +179,7 @@
assertNull( postDelete );
}
+
@Test
public void deleteUUID() {
MapManager mm = mmf.createMapManager( this.scope );
@@ -163,6 +200,7 @@
assertNull( postDelete );
}
+
@Test
public void deleteLong() {
MapManager mm = mmf.createMapManager( this.scope );
@@ -191,14 +229,17 @@
mm.putString( null, null );
}
+
@Test( expected = NullPointerException.class )
public void nullInputLong() {
MapManager mm = mmf.createMapManager( this.scope );
mm.putLong( null, null );
}
+
+
@Test( expected = NullPointerException.class )
- public void nullInputUUID() {
+ public void nullInputUUID() {
MapManager mm = mmf.createMapManager( this.scope );
mm.putUuid( null, null );