You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by to...@apache.org on 2013/11/28 01:16:01 UTC

[1/2] git commit: Updated tests on serialization strategies to have 100% coverage and full input validation.

Updated Branches:
  refs/heads/two-dot-o ac634a1d0 -> a022fb174


Updated  tests on serialization strategies to have 100% coverage and full input validation.


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/c904e157
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/c904e157
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/c904e157

Branch: refs/heads/two-dot-o
Commit: c904e157fd5a076cae470f44a47e074d3d3993ec
Parents: ac634a1
Author: Todd Nine <to...@apache.org>
Authored: Wed Nov 27 16:42:07 2013 -0700
Committer: Todd Nine <to...@apache.org>
Committed: Wed Nov 27 16:42:07 2013 -0700

----------------------------------------------------------------------
 .../collection/CollecitonManagerImpl.java       |  15 --
 .../collection/CollectionContextImpl.java       |  10 +
 .../collection/mvcc/entity/MvccEntityImpl.java  |  11 ++
 .../mvcc/entity/MvccLogEntryImpl.java           |  20 +-
 .../MvccEntitySerializationStrategy.java        |   3 +-
 .../MvccEntitySerializationStrategyImpl.java    |  57 ++----
 .../MvccLogEntrySerializationStrategy.java      |   7 +-
 .../MvccLogEntrySerializationStrategyImpl.java  | 103 ++++++-----
 ...MvccEntitySerializationStrategyImplTest.java |  87 +++++++++
 ...ccLogEntrySerializationStrategyImplTest.java | 181 ++++++++++++++++++-
 .../persistence/model/util/UUIDGenerator.java   |  36 ++--
 11 files changed, 391 insertions(+), 139 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollecitonManagerImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollecitonManagerImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollecitonManagerImpl.java
deleted file mode 100644
index 5a2f708..0000000
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollecitonManagerImpl.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.apache.usergrid.persistence.collection;
-
-
-/**
- * @author tnine
- */
-public class CollecitonManagerImpl {
-
-    private final CollectionContext context;
-
-
-    public CollecitonManagerImpl( final CollectionContext context ) {
-        this.context = context;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollectionContextImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollectionContextImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollectionContextImpl.java
index 371bde9..2173c31 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollectionContextImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/CollectionContextImpl.java
@@ -79,4 +79,14 @@ public class CollectionContextImpl implements CollectionContext {
         result = 31 * result + name.hashCode();
         return result;
     }
+
+
+    @Override
+    public String toString() {
+        return "CollectionContextImpl{" +
+                "applicationId=" + applicationId +
+                ", ownerId=" + ownerId +
+                ", name='" + name + '\'' +
+                '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccEntityImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccEntityImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccEntityImpl.java
index 5c01cb5..c560db4 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccEntityImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccEntityImpl.java
@@ -92,4 +92,15 @@ public class MvccEntityImpl implements MvccEntity {
         result = 31 * result + getVersion().hashCode();
         return result;
     }
+
+
+    @Override
+    public String toString() {
+        return "MvccEntityImpl{" +
+                "context=" + context +
+                ", entityId=" + entityId +
+                ", version=" + version +
+                ", entity=" + entity +
+                '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccLogEntryImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccLogEntryImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccLogEntryImpl.java
index f0f803b..0d9d6fc 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccLogEntryImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/mvcc/entity/MvccLogEntryImpl.java
@@ -8,6 +8,7 @@ import org.apache.usergrid.persistence.collection.CollectionContext;
 
 /**
  * The simple implementation of a log entry
+ *
  * @author tnine
  */
 public class MvccLogEntryImpl implements MvccLogEntry {
@@ -18,7 +19,7 @@ public class MvccLogEntryImpl implements MvccLogEntry {
     private final Stage stage;
 
 
-    public MvccLogEntryImpl(final CollectionContext context, final UUID entityId, final UUID version,
+    public MvccLogEntryImpl( final CollectionContext context, final UUID entityId, final UUID version,
                              final Stage stage ) {
         this.context = context;
         this.entityId = entityId;
@@ -68,13 +69,15 @@ public class MvccLogEntryImpl implements MvccLogEntry {
         if ( !entityId.equals( that.entityId ) ) {
             return false;
         }
-        if ( stage != that.stage ) {
+        if ( !version.equals( that.version ) ) {
             return false;
         }
-        if ( !version.equals( that.version ) ) {
+
+        if ( stage != that.stage ) {
             return false;
         }
 
+
         return true;
     }
 
@@ -87,4 +90,15 @@ public class MvccLogEntryImpl implements MvccLogEntry {
         result = 31 * result + stage.hashCode();
         return result;
     }
+
+
+    @Override
+    public String toString() {
+        return "MvccLogEntryImpl{" +
+                "context=" + context +
+                ", entityId=" + entityId +
+                ", version=" + version +
+                ", stage=" + stage +
+                '}';
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategy.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategy.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategy.java
index 0d3d112..3d16fe1 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategy.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategy.java
@@ -48,7 +48,8 @@ public interface MvccEntitySerializationStrategy
      * @return A list of entities up to max size ordered from max(UUID)=> min(UUID).  The return value should be null safe
      * and return an empty list when there are no matches
      */
-    public List<MvccEntity> load( CollectionContext context, UUID entityId, UUID version, int maxSize );
+    public List<MvccEntity> load( CollectionContext context, UUID entityId, UUID version, int maxSize )
+            throws ConnectionException;
 
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImpl.java
index 4b8840d..6030866 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImpl.java
@@ -30,15 +30,12 @@ import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
 import com.netflix.astyanax.model.Column;
 import com.netflix.astyanax.model.ColumnFamily;
 import com.netflix.astyanax.model.ColumnList;
-import com.netflix.astyanax.model.ColumnSlice;
 import com.netflix.astyanax.serializers.AbstractSerializer;
 import com.netflix.astyanax.serializers.ObjectSerializer;
 import com.netflix.astyanax.serializers.UUIDSerializer;
 
 
-/**
- * @author tnine
- */
+/** @author tnine */
 @Singleton
 public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializationStrategy, Migration {
 
@@ -85,14 +82,11 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
         Preconditions.checkNotNull( version, "version is required" );
 
 
-        final UUID start = null;
-        final UUID end = null;
-
         Column<UUID> column;
 
         try {
-            column = keyspace.prepareQuery( CF_ENTITY_DATA ).getKey( entityId )
-                              .getColumn( version ).execute().getResult();
+            column = keyspace.prepareQuery( CF_ENTITY_DATA ).getKey( entityId ).getColumn( version ).execute()
+                             .getResult();
         }
 
         catch ( NotFoundException e ) {
@@ -100,19 +94,14 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
             return null;
         }
 
-        if ( column == null ) {
-            return null;
-        }
-
-
-        return new MvccEntityImpl( context, entityId, version, column.getValue(SER) );
 
+        return new MvccEntityImpl( context, entityId, version, column.getValue( SER ) );
     }
 
 
     @Override
     public List<MvccEntity> load( final CollectionContext context, final UUID entityId, final UUID version,
-                                  final int maxSize ) {
+                                  final int maxSize ) throws ConnectionException {
 
         Preconditions.checkNotNull( context, "context is required" );
         Preconditions.checkNotNull( entityId, "entity id is required" );
@@ -120,22 +109,9 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
         Preconditions.checkArgument( maxSize > 0, "max Size must be greater than 0" );
 
 
-        ColumnList<UUID> columns;
+        ColumnList<UUID> columns = keyspace.prepareQuery( CF_ENTITY_DATA ).getKey( entityId )
+                                           .withColumnRange( version, null, false, maxSize ).execute().getResult();
 
-        try {
-
-
-            columns = keyspace.prepareQuery( CF_ENTITY_DATA ).getKey( entityId )
-                              .withColumnRange( version, null, false, maxSize ).execute().getResult();
-        }
-
-        catch ( ConnectionException e ) {
-            throw new RuntimeException( "Unable to load column data", e );
-        }
-
-        if ( columns == null ) {
-            return Collections.EMPTY_LIST;
-        }
 
         List<MvccEntity> results = new ArrayList<MvccEntity>( columns.size() );
 
@@ -166,6 +142,10 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
 
     @Override
     public MutationBatch delete( final CollectionContext context, final UUID entityId, final UUID version ) {
+        Preconditions.checkNotNull( context, "context is required" );
+        Preconditions.checkNotNull( entityId, "entity id is required" );
+        Preconditions.checkNotNull( version, "version is required" );
+
 
         return doWrite( entityId, new RowOp() {
             @Override
@@ -189,9 +169,7 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
     }
 
 
-    /**
-     * Do the write on the correct row for the entity id with the operation
-     */
+    /** Do the write on the correct row for the entity id with the operation */
     private MutationBatch doWrite( UUID entityId, RowOp op ) {
         final MutationBatch batch = keyspace.prepareMutationBatch();
 
@@ -201,21 +179,18 @@ public class MvccEntitySerializationStrategyImpl implements MvccEntitySerializat
     }
 
 
-    /**
-     * Simple callback to perform puts and deletes with a common row setup code
-     */
+    /** Simple callback to perform puts and deletes with a common row setup code */
     private static interface RowOp {
 
-        /**
-         * The operation to perform on the row
-         */
+        /** The operation to perform on the row */
         void doOp( ColumnListMutation<UUID> colMutation );
     }
 
 
     /**
      * TODO: Serializer for the entity. This just uses object serialization, change this to use SMILE before production!
-     * We want to retain the Optional wrapper.  It helps us easily mark something as cleaned without removing the data
+     * We want to retain the Optional wrapper.  It helps us easily mark something as cleaned without removing the column
+     * and makes it obvious that the entity could be missing in the api
      */
     private static class EntitySerializer extends AbstractSerializer<Optional<Entity>> {
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategy.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategy.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategy.java
index a249522..3206e60 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategy.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategy.java
@@ -29,9 +29,9 @@ public interface MvccLogEntrySerializationStrategy
      *
      * @param context The context to persist the entity into
      * @param entityId The entity id to load
-     * @param version The version to load.  This will return the version <= the given version
+     * @param version The version to load.  This will return the version == the given version
      *
-     * @return The deserialized version of the entity.  Null if no version <= the current version exists, or the entity does not exist
+     * @return The deserialized version of the log entry.  Null if no version == the current version exists
      */
     public MvccLogEntry load( final CollectionContext context, final UUID entityId, final UUID version )
             throws ConnectionException;
@@ -46,7 +46,8 @@ public interface MvccLogEntrySerializationStrategy
      *
      * @return A list of entities up to max size ordered from max(UUID)=> min(UUID)
      */
-    public List<MvccLogEntry> load( CollectionContext context, UUID entityId, UUID version, int maxSize );
+    public List<MvccLogEntry> load( CollectionContext context, UUID entityId, UUID version, int maxSize )
+            throws ConnectionException;
 
     /**
      * Delete the stage from the context with the given entityId and version

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImpl.java b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImpl.java
index f6217a2..a418ecc 100644
--- a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImpl.java
+++ b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImpl.java
@@ -1,6 +1,8 @@
 package org.apache.usergrid.persistence.collection.serialization;
 
 
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -25,11 +27,12 @@ import com.google.inject.name.Named;
 import com.netflix.astyanax.ColumnListMutation;
 import com.netflix.astyanax.Keyspace;
 import com.netflix.astyanax.MutationBatch;
-import com.netflix.astyanax.connectionpool.OperationResult;
 import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
 import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
 import com.netflix.astyanax.model.Column;
 import com.netflix.astyanax.model.ColumnFamily;
+import com.netflix.astyanax.model.ColumnList;
+import com.netflix.astyanax.serializers.AbstractSerializer;
 import com.netflix.astyanax.serializers.UUIDSerializer;
 
 
@@ -43,14 +46,11 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
 
     public static final String TIMEOUT_PROP = "collection.stage.transient.timeout";
 
+    private static final StageSerializer SER = new StageSerializer();
+
     private static final ColumnFamily<UUID, UUID> CF_ENTITY_LOG =
             new ColumnFamily<UUID, UUID>( "Entity_Log", UUIDSerializer.get(), UUIDSerializer.get() );
 
-    /**
-     * Used for caching the byte => stage mapping
-     */
-    private static final StageCache CACHE = new StageCache();
-
 
     protected final Keyspace keyspace;
     protected final int timeout;
@@ -71,7 +71,6 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
 
         final Stage stage = entry.getStage();
         final UUID colName = entry.getVersion();
-        final byte colValue = stage.getId();
 
         return doWrite( entry.getContext(), entry.getEntityId(), new RowOp() {
             @Override
@@ -79,12 +78,12 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
 
                 //Write the stage with a timeout, it's set as transient
                 if ( stage.isTransient() ) {
-                    colMutation.putColumn( colName, colValue, timeout );
+                    colMutation.putColumn( colName, stage, SER, timeout );
                     return;
                 }
 
                 //otherwise it's persistent, write it with no expiration
-                colMutation.putColumn( colName, colValue );
+                colMutation.putColumn( colName, stage, SER, null );
             }
         } );
     }
@@ -98,28 +97,18 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
         Preconditions.checkNotNull( version, "version is required" );
 
 
-        Column<UUID> result = null;
+        Column<UUID> result;
 
         try {
-            OperationResult<Column<UUID>>
-                    foo = keyspace.prepareQuery( CF_ENTITY_LOG ).getKey( entityId ).getColumn( version ).execute();
-
-            result = foo.getResult();
+            result = keyspace.prepareQuery( CF_ENTITY_LOG ).getKey( entityId ).getColumn( version ).execute()
+                             .getResult();
         }
         catch ( NotFoundException nfe ) {
             return null;
         }
 
-        if ( result == null ) {
-            return null;
-        }
-
-        final byte stored = result.getByteValue();
-
-
-        final Stage stage = CACHE.getStage( stored );
 
-        Preconditions.checkNotNull( "No stage was found for byte value " + stored + ".  This is a migration data bug" );
+        final Stage stage = result.getValue( SER );
 
         return new MvccLogEntryImpl( context, entityId, version, stage );
     }
@@ -127,8 +116,27 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
 
     @Override
     public List<MvccLogEntry> load( final CollectionContext context, final UUID entityId, final UUID version,
-                                    final int maxSize ) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+                                    final int maxSize ) throws ConnectionException {
+        Preconditions.checkNotNull( context, "context is required" );
+        Preconditions.checkNotNull( entityId, "entity id is required" );
+        Preconditions.checkNotNull( version, "version is required" );
+        Preconditions.checkArgument( maxSize > 0, "max Size must be greater than 0" );
+
+
+        ColumnList<UUID> columns = keyspace.prepareQuery( CF_ENTITY_LOG ).getKey( entityId )
+                                           .withColumnRange( version, null, false, maxSize ).execute().getResult();
+
+
+        List<MvccLogEntry> results = new ArrayList<MvccLogEntry>( columns.size() );
+
+        for ( Column<UUID> col : columns ) {
+            final UUID storedVersion = col.getName();
+            final Stage stage = col.getValue( SER );
+
+            results.add( new MvccLogEntryImpl( context, entityId, storedVersion, stage ) );
+        }
+
+        return results;
     }
 
 
@@ -160,14 +168,10 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
     }
 
 
-    /**
-     * Simple callback to perform puts and deletes with a common row setup code
-     */
+    /** Simple callback to perform puts and deletes with a common row setup code */
     private static interface RowOp {
 
-        /**
-         * The operation to perform on the row
-         */
+        /** The operation to perform on the row */
         void doOp( ColumnListMutation<UUID> colMutation );
     }
 
@@ -187,9 +191,7 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
     }
 
 
-    /**
-     * Internal stage cache
-     */
+    /** Internal stage cache */
     private static class StageCache {
         private Map<Byte, Stage> values = new HashMap<Byte, Stage>( Stage.values().length );
 
@@ -199,21 +201,38 @@ public class MvccLogEntrySerializationStrategyImpl implements MvccLogEntrySerial
 
                 final byte stageValue = stage.getId();
 
-                if ( values.containsKey( stageValue ) ) {
-                    throw new RuntimeException(
-                            "There are two Stages assigned to the byte " + stageValue + ".  This is a bug" );
-                }
-
                 values.put( stageValue, stage );
             }
         }
 
 
-        /**
-         * Get the stage with the byte value
-         */
+        /** Get the stage with the byte value */
         private Stage getStage( final byte value ) {
             return values.get( value );
         }
     }
+
+
+    public static class StageSerializer extends AbstractSerializer<Stage> {
+
+        /** Used for caching the byte => stage mapping */
+        private static final StageCache CACHE = new StageCache();
+
+
+        @Override
+        public ByteBuffer toByteBuffer( final Stage obj ) {
+            ByteBuffer buff = ByteBuffer.allocate( 1 );
+            buff.put( obj.getId() );
+            buff.rewind();
+            return buff;
+        }
+
+
+        @Override
+        public Stage fromByteBuffer( final ByteBuffer byteBuffer ) {
+            final byte value  = byteBuffer.get();
+
+            return CACHE.getStage(value);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImplTest.java
index a3bcead..ffa868e 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccEntitySerializationStrategyImplTest.java
@@ -340,4 +340,91 @@ public class MvccEntitySerializationStrategyImplTest {
 
         assertEquals( 0, entities.size() );
     }
+
+
+    @Test(expected = NullPointerException.class)
+    public void writeParams() throws ConnectionException {
+       serializationStrategy.write( null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamContext() throws ConnectionException {
+       serializationStrategy.delete( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamEntityId() throws ConnectionException {
+
+        serializationStrategy
+                .delete( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamVersion() throws ConnectionException {
+
+        serializationStrategy
+                .delete( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamContext() throws ConnectionException {
+       serializationStrategy.load( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamEntityId() throws ConnectionException {
+
+        serializationStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamVersion() throws ConnectionException {
+
+        serializationStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamContext() throws ConnectionException {
+       serializationStrategy.load( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), 1 );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamEntityId() throws ConnectionException {
+
+        serializationStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID(), 1 );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamVersion() throws ConnectionException {
+
+        serializationStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null, 1 );
+    }
+
+
+    @Test(expected = IllegalArgumentException.class)
+    public void loadListParamSize() throws ConnectionException {
+
+        serializationStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), 0 );
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImplTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImplTest.java b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImplTest.java
index c66fac2..195443e 100644
--- a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImplTest.java
+++ b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/serialization/MvccLogEntrySerializationStrategyImplTest.java
@@ -2,6 +2,7 @@ package org.apache.usergrid.persistence.collection.serialization;
 
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
@@ -29,15 +30,11 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 
 
-/**
- * @author tnine
- */
+/** @author tnine */
 public class MvccLogEntrySerializationStrategyImplTest {
 
 
-    /**
-     * Set our timeout to 1 seconds.  If it works for 1 seconds, we'll be good a any value
-     */
+    /** Set our timeout to 1 seconds.  If it works for 1 seconds, we'll be good a any value */
     private static final int TIMEOUT = 1;
 
 
@@ -80,6 +77,84 @@ public class MvccLogEntrySerializationStrategyImplTest {
 
 
     @Test
+    public void loadNoData() throws ConnectionException {
+
+        final UUID applicationId = UUIDGenerator.newTimeUUID();
+        final String name = "test";
+
+
+        CollectionContext context = new CollectionContextImpl( applicationId, applicationId, name );
+
+
+        final UUID uuid = UUIDGenerator.newTimeUUID();
+        final UUID version = UUIDGenerator.newTimeUUID();
+
+
+        MvccLogEntry returned = logEntryStrategy.load( context, uuid, version );
+
+        assertNull( "Returned value should not exist", returned );
+    }
+
+
+    @Test
+    public void getMultipleEntries() throws ConnectionException {
+
+        final UUID applicationId = UUIDGenerator.newTimeUUID();
+        final String name = "test";
+
+
+        CollectionContext context = new CollectionContextImpl( applicationId, applicationId, name );
+
+
+        final UUID uuid = UUIDGenerator.newTimeUUID();
+
+        int count = 10;
+
+        final UUID[] versions = new UUID[count];
+        final Stage COMPLETE = Stage.COMPLETE;
+        final MvccLogEntry[] entries = new MvccLogEntry[count];
+
+
+        for ( int i = 0; i < count; i++ ) {
+            versions[i] = UUIDGenerator.newTimeUUID();
+
+            entries[i] = new MvccLogEntryImpl( context, uuid, versions[i], COMPLETE );
+            logEntryStrategy.write( entries[i] ).execute();
+
+            //Read it back
+
+            MvccLogEntry returned = logEntryStrategy.load( context, uuid, versions[i] );
+
+            assertNotNull( "Returned value should not be null", returned );
+
+            assertEquals( "Returned should equal the saved", entries[i], returned );
+        }
+
+        //now do a range scan from the end
+
+        List<MvccLogEntry> results = logEntryStrategy.load( context, uuid, versions[count - 1], count );
+
+        assertEquals( count, results.size() );
+
+        for ( int i = 0; i < count; i++ ) {
+            final MvccLogEntry saved = entries[count - i - 1];
+            final MvccLogEntry returned = results.get( i );
+
+            assertEquals( "Entry was not equal to the saved value", saved, returned );
+        }
+
+        //now delete them all and ensure we get no results back
+        for ( int i = 0; i < count; i++ ) {
+            logEntryStrategy.delete( context, uuid, versions[i] ).execute();
+        }
+
+        results = logEntryStrategy.load( context, uuid, versions[versions.length - 1], versions.length );
+
+        assertEquals( "All log entries were deleted", 0, results.size() );
+    }
+
+
+    @Test
     public void transientTimeout() throws ConnectionException, InterruptedException {
 
         final UUID applicationId = UUIDGenerator.newTimeUUID();
@@ -117,9 +192,94 @@ public class MvccLogEntrySerializationStrategyImplTest {
     }
 
 
-    /**
-     * Mapper that will change which module we implement based on the test case
-     */
+    @Test(expected = NullPointerException.class)
+    public void writeParams() throws ConnectionException {
+        logEntryStrategy.write( null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamContext() throws ConnectionException {
+        logEntryStrategy.delete( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamEntityId() throws ConnectionException {
+
+        logEntryStrategy
+                .delete( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void deleteParamVersion() throws ConnectionException {
+
+        logEntryStrategy
+                .delete( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamContext() throws ConnectionException {
+        logEntryStrategy.load( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamEntityId() throws ConnectionException {
+
+        logEntryStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID() );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadParamVersion() throws ConnectionException {
+
+        logEntryStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamContext() throws ConnectionException {
+        logEntryStrategy.load( null, UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), 1 );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamEntityId() throws ConnectionException {
+
+        logEntryStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        null, UUIDGenerator.newTimeUUID(), 1 );
+    }
+
+
+    @Test(expected = NullPointerException.class)
+    public void loadListParamVersion() throws ConnectionException {
+
+        logEntryStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), null, 1 );
+    }
+
+
+    @Test(expected = IllegalArgumentException.class)
+    public void loadListParamSize() throws ConnectionException {
+
+        logEntryStrategy
+                .load( new CollectionContextImpl( UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), "test" ),
+                        UUIDGenerator.newTimeUUID(), UUIDGenerator.newTimeUUID(), 0 );
+    }
+
+
+    /** Mapper that will change which module we implement based on the test case */
     public static class TimeoutModMapper implements GuiceBerryEnvSelector {
 
         @Override
@@ -127,7 +287,8 @@ public class MvccLogEntrySerializationStrategyImplTest {
 
             //in this edge case, we want to truncate the timeout to 1 second for this test, override the env to use
             //this module setup
-            if ( (MvccLogEntrySerializationStrategyImplTest.class.getName()+".transientTimeout").equals( testDescription.getName() ) ) {
+            if ( ( MvccLogEntrySerializationStrategyImplTest.class.getName() + ".transientTimeout" )
+                    .equals( testDescription.getName() ) ) {
                 return TimeoutEnv.class;
             }
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c904e157/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
index 687e27b..d8f22af 100644
--- a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
+++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
@@ -17,12 +17,10 @@ import com.fasterxml.uuid.impl.TimeBasedGenerator;
  * @author: tnine
  *
  */
-public class UUIDGenerator
-{
+public class UUIDGenerator {
 
 
-    private static final TimestampSynchronizer synchronizer = new TimestampSynchronizer()
-    {
+    private static final TimestampSynchronizer synchronizer = new TimestampSynchronizer() {
 
         /**
          * Pointer to the last value we returned
@@ -38,8 +36,7 @@ public class UUIDGenerator
 
 
         @Override
-        protected long initialize() throws IOException
-        {
+        protected long initialize() throws IOException {
 
             last = System.currentTimeMillis();
             return last;
@@ -47,29 +44,24 @@ public class UUIDGenerator
 
 
         @Override
-        protected void deactivate() throws IOException
-        {
+        protected void deactivate() throws IOException {
             //no op
         }
 
 
         @Override
-        protected long update( long now ) throws IOException
-        {
+        protected long update( long now ) throws IOException {
             /**
-             * It's greater
+             * Our timestamp is greater just use that
              */
-            if ( now > last )
-            {
+            if ( now > last ) {
                 last = now;
                 ticks.set( 0 );
                 return last;
             }
 
             //we have the same value (since now should always be increasing) increment a tick
-            last = now + ticks.incrementAndGet();
-
-            return last;
+            return last + ticks.incrementAndGet();
         }
     };
 
@@ -81,14 +73,11 @@ public class UUIDGenerator
     /**
      * Lame, but required
      */
-    static
-    {
-        try
-        {
+    static {
+        try {
             timer = new UUIDTimer( random, synchronizer );
         }
-        catch ( IOException e )
-        {
+        catch ( IOException e ) {
             throw new RuntimeException( "Couldn't intialize timer", e );
         }
     }
@@ -99,8 +88,7 @@ public class UUIDGenerator
 
 
     /** Create a new time uuid */
-    public static UUID newTimeUUID()
-    {
+    public static UUID newTimeUUID() {
         return generator.generate();
     }
 }


[2/2] git commit: Added tests for the UUID Generator

Posted by to...@apache.org.
Added tests for the UUID Generator


Project: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/commit/a022fb17
Tree: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/tree/a022fb17
Diff: http://git-wip-us.apache.org/repos/asf/incubator-usergrid/diff/a022fb17

Branch: refs/heads/two-dot-o
Commit: a022fb1744f439a661affb1ad6729cb0b4c1c5ce
Parents: c904e15
Author: Todd Nine <to...@apache.org>
Authored: Wed Nov 27 17:15:55 2013 -0700
Committer: Todd Nine <to...@apache.org>
Committed: Wed Nov 27 17:15:55 2013 -0700

----------------------------------------------------------------------
 .../persistence/model/util/UUIDGenerator.java   |   7 +-
 .../model/util/UUIDGeneratorTest.java           | 119 +++++++++++++++++++
 2 files changed, 122 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a022fb17/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
index d8f22af..ed03660 100644
--- a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
+++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/util/UUIDGenerator.java
@@ -20,7 +20,7 @@ import com.fasterxml.uuid.impl.TimeBasedGenerator;
 public class UUIDGenerator {
 
 
-    private static final TimestampSynchronizer synchronizer = new TimestampSynchronizer() {
+    private static final TimestampSynchronizer synchronize = new TimestampSynchronizer() {
 
         /**
          * Pointer to the last value we returned
@@ -75,7 +75,7 @@ public class UUIDGenerator {
      */
     static {
         try {
-            timer = new UUIDTimer( random, synchronizer );
+            timer = new UUIDTimer( random, synchronize );
         }
         catch ( IOException e ) {
             throw new RuntimeException( "Couldn't intialize timer", e );
@@ -83,8 +83,7 @@ public class UUIDGenerator {
     }
 
 
-    private static final TimeBasedGenerator generator =
-            new TimeBasedGenerator( EthernetAddress.fromInterface(), timer );
+    private static final TimeBasedGenerator generator = new TimeBasedGenerator( EthernetAddress.fromInterface(), timer );
 
 
     /** Create a new time uuid */

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a022fb17/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/util/UUIDGeneratorTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/util/UUIDGeneratorTest.java b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/util/UUIDGeneratorTest.java
new file mode 100644
index 0000000..ef1a9e9
--- /dev/null
+++ b/stack/corepersistence/model/src/test/java/org/apache/usergrid/persistence/model/util/UUIDGeneratorTest.java
@@ -0,0 +1,119 @@
+package org.apache.usergrid.persistence.model.util;
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.junit.Test;
+
+import com.fasterxml.uuid.UUIDComparator;
+import com.google.common.collect.Sets;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+
+/** @author tnine */
+public class UUIDGeneratorTest {
+
+
+    @Test
+    public void testOrderingConcurrency() throws InterruptedException, ExecutionException {
+
+
+        //either all processor count, or 2 threads
+        final int numberThreads = Math.max( Runtime.getRuntime().availableProcessors(), 2 );
+
+        /**
+         * 10k  uuids per thread
+         */
+        final int count = 10000;
+
+        ExecutorService executor = Executors.newFixedThreadPool( numberThreads );
+
+        List<UUIDConsumer> consumers = new ArrayList<UUIDConsumer>( numberThreads );
+
+        for ( int i = 0; i < numberThreads; i++ ) {
+            consumers.add( new UUIDConsumer( count ) );
+        }
+
+        List<Future<Void>> futures = executor.invokeAll( consumers );
+
+        //wait for them all to finish
+        for(Future<Void> future: futures){
+            future.get();
+        }
+
+        //now validate each one is in order and does not intersect with any other
+        for(int i = 0; i < numberThreads; i ++){
+
+            UUIDConsumer current = consumers.get( i );
+
+            current.validateOrder();
+
+            for(int j = i+1; j < numberThreads; j++){
+                current.noIntersect( consumers.get( j ) );
+            }
+        }
+
+    }
+
+
+    private static class UUIDConsumer implements Callable<Void> {
+
+        private final int toGenerate;
+        private final List<UUID> results;
+
+
+        private UUIDConsumer( final int toGenerate ) {
+            this.toGenerate = toGenerate;
+            this.results = new ArrayList<UUID>( toGenerate );
+        }
+
+
+        /**
+         * Validate that each UUID is greater than than it's previous entry when comparing them
+         */
+        public void validateOrder() {
+
+            for(int i = 0; i < toGenerate -1; i ++){
+                int comparison = UUIDComparator.staticCompare( results.get( i ), results.get( i+1 ) );
+                assertTrue(comparison < 0);
+            }
+        }
+
+
+        /**
+         * Validate the other UUID consumer does not have any intersection with this consumer
+         * @param other
+         */
+        public void noIntersect(UUIDConsumer other){
+
+            Set<UUID> firstSet = new HashSet<UUID>(results);
+            Set<UUID> otherSet = new HashSet<UUID>(other.results);
+
+            Set<UUID> intersection = Sets.intersection(firstSet, otherSet);
+
+            assertEquals("No UUID Generator should have a UUID that intersects with another UUID", 0, intersection.size());
+        }
+
+
+        @Override
+        public Void call() throws Exception {
+            for ( int i = 0; i < toGenerate; i++ ) {
+                this.results.add( UUIDGenerator.newTimeUUID() );
+            }
+
+            return null;
+        }
+    }
+}