Add new tool for scanning unique values.  Include option to skip read repair in 
the methods that load entities from the unique index.


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

Branch: refs/heads/master
Commit: 06f77d7b385efdcb3655035e895d89f99710a70a
Parents: 9efa3b4
Author: Michael Russo <[email protected]>
Authored: Tue Jun 21 14:29:50 2016 -0700
Committer: Michael Russo <[email protected]>
Committed: Tue Jun 21 14:29:50 2016 -0700

----------------------------------------------------------------------
 .../corepersistence/CpEntityManager.java        |   9 +-
 .../usergrid/persistence/EntityManager.java     |   2 +-
 .../collection/EntityCollectionManager.java     |   3 +-
 .../impl/EntityCollectionManagerImpl.java       |   7 +-
 .../UniqueValueSerializationStrategyImpl.java   |  15 +-
 .../collection/EntityCollectionManagerIT.java   |  63 +++--
 .../services/AbstractCollectionService.java     |   8 +-
 .../services/AbstractConnectionsService.java    |   6 +-
 .../usergrid/tools/UniqueValueScanner.java      | 245 +++++++++++++++++++
 9 files changed, 314 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
----------------------------------------------------------------------
diff --git 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
index 82c4c87..ab62b36 100644
--- 
a/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
+++ 
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/CpEntityManager.java
@@ -853,10 +853,9 @@ public class CpEntityManager implements EntityManager {
     }
 
     @Override
-    public Entity getUniqueEntityFromAlias( String collectionType, String 
aliasType ){
-        String collName = Schema.defaultCollectionName( collectionType );
-
+    public Entity getUniqueEntityFromAlias(String collectionType, String 
aliasType, boolean useReadRepair){
 
+        String collName = Schema.defaultCollectionName( collectionType );
         String propertyName = Schema.getDefaultSchema().aliasProperty( 
collName );
 
         Timer.Context repairedEntityGet = entGetRepairedEntityTimer.time();
@@ -867,7 +866,7 @@ public class CpEntityManager implements EntityManager {
         StringField uniqueLookupRepairField =  new StringField( propertyName, 
aliasType.toString());
 
         Observable<FieldSet> fieldSetObservable = ecm.getEntitiesFromFields(
-            Inflector.getInstance().singularize( collectionType ), 
Arrays.<Field>asList( uniqueLookupRepairField ) );
+            Inflector.getInstance().singularize( collectionType ), 
Arrays.<Field>asList( uniqueLookupRepairField ), useReadRepair);
 
         if(fieldSetObservable == null){
 
@@ -901,7 +900,7 @@ public class CpEntityManager implements EntityManager {
         StringField uniqueLookupRepairField =  new StringField( propertyName, 
aliasType);
 
         Observable<FieldSet> fieldSetObservable = ecm.getEntitiesFromFields(
-            Inflector.getInstance().singularize( collectionType ), 
Collections.singletonList(uniqueLookupRepairField));
+            Inflector.getInstance().singularize( collectionType ), 
Collections.singletonList(uniqueLookupRepairField), true);
 
         if(fieldSetObservable == null){
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
----------------------------------------------------------------------
diff --git 
a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java 
b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
index ef96f10..53a7a89 100644
--- 
a/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
+++ 
b/stack/core/src/main/java/org/apache/usergrid/persistence/EntityManager.java
@@ -709,7 +709,7 @@ public interface EntityManager {
     public void flushManagerCaches();
 
 
-    public Entity getUniqueEntityFromAlias( String aliasType, String 
aliasValue );
+    public Entity getUniqueEntityFromAlias(String aliasType, String 
aliasValue, boolean useReadRepair);
 
     public UUID getUniqueIdFromAlias( String aliasType, String aliasValue );
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/EntityCollectionManager.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/EntityCollectionManager.java
 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/EntityCollectionManager.java
index 22fbb5f..ed43775 100644
--- 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/EntityCollectionManager.java
+++ 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/EntityCollectionManager.java
@@ -76,9 +76,10 @@ public interface EntityCollectionManager {
      * Get a fieldset of all fields from the entities
      * @param entityType The type of entity.  From the "type" field in the id.
      * @param fields The collection of fields to search
+     * @param useReadRepair
      * @return
      */
-    Observable<FieldSet> getEntitiesFromFields( String entityType, 
Collection<Field> fields );
+    Observable<FieldSet> getEntitiesFromFields(String entityType, 
Collection<Field> fields, boolean useReadRepair);
 
     /**
      * Gets the Id for a field

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
index 77e452f..1ccc18f 100644
--- 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
+++ 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/impl/EntityCollectionManagerImpl.java
@@ -65,7 +65,6 @@ import 
org.apache.usergrid.persistence.core.util.ValidationUtils;
 import org.apache.usergrid.persistence.model.entity.Entity;
 import org.apache.usergrid.persistence.model.entity.Id;
 import org.apache.usergrid.persistence.model.field.Field;
-import org.apache.usergrid.persistence.model.util.EntityUtils;
 import org.apache.usergrid.persistence.model.util.UUIDGenerator;
 
 import com.codahale.metrics.Timer;
@@ -82,7 +81,6 @@ import com.netflix.astyanax.serializers.StringSerializer;
 
 import rx.Observable;
 import rx.Subscriber;
-import rx.functions.Action0;
 
 
 /**
@@ -327,7 +325,7 @@ public class EntityCollectionManagerImpl implements 
EntityCollectionManager {
      * Retrieves all entities that correspond to each field given in the 
Collection.
      */
     @Override
-    public Observable<FieldSet> getEntitiesFromFields( final String type, 
final Collection<Field> fields ) {
+    public Observable<FieldSet> getEntitiesFromFields(final String type, final 
Collection<Field> fields, boolean useReadRepair) {
         final Observable<FieldSet> fieldSetObservable = Observable.just( 
fields ).map( fields1 -> {
             try {
 
@@ -408,7 +406,7 @@ public class EntityCollectionManagerImpl implements 
EntityCollectionManager {
                     response.addEntity( expectedUnique.getField(), entity );
                 }
 
-                if ( deleteBatch.getRowCount() > 0 ) {
+                if ( useReadRepair && deleteBatch.getRowCount() > 0 ) {
 
                     deleteBatch.execute();
 
@@ -436,7 +434,6 @@ public class EntityCollectionManagerImpl implements 
EntityCollectionManager {
                 }
 
 
-
                 return response;
             }
             catch ( ConnectionException e ) {

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
index 622ebef..f7d5199 100644
--- 
a/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
+++ 
b/stack/corepersistence/collection/src/main/java/org/apache/usergrid/persistence/collection/serialization/impl/UniqueValueSerializationStrategyImpl.java
@@ -64,7 +64,7 @@ import com.netflix.astyanax.util.RangeBuilder;
 public abstract class UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
     implements UniqueValueSerializationStrategy {
 
-    private static final Logger log = LoggerFactory.getLogger( 
UniqueValueSerializationStrategyImpl.class );
+    private static final Logger logger = LoggerFactory.getLogger( 
UniqueValueSerializationStrategyImpl.class );
 
 
     private final MultiTenantColumnFamily<ScopedRowKey<FieldKey>, 
EntityVersion>
@@ -159,7 +159,7 @@ public abstract class 
UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
 
 
             //we purposefully leave out TTL.  Worst case we issue deletes 
against tombstoned columns
-            //best case, we clean up an invalid secondary index entry when the 
log is used
+            //best case, we clean up an invalid secondary index entry when the 
logger is used
             @Override
             public void doLog( final ColumnListMutation<UniqueFieldEntry> 
colMutation ) {
                 colMutation.putColumn( uniqueFieldEntry, COL_VALUE );
@@ -225,8 +225,8 @@ public abstract class 
UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
             ScopedRowKey.fromKey( applicationId, entityKey ) ) );
 
 
-        if ( log.isTraceEnabled() ) {
-            log.trace( "Writing unique value version={} name={} value={} ",
+        if ( logger.isTraceEnabled() ) {
+            logger.trace( "Writing unique value version={} name={} value={} ",
                     uniqueValue.getEntityVersion(), 
uniqueValue.getField().getName(),
                     uniqueValue.getField().getValue()
                 );
@@ -296,6 +296,13 @@ public abstract class 
UniqueValueSerializationStrategyImpl<FieldKey, EntityKey>
             final UniqueValueImpl uniqueValue =
                 new UniqueValueImpl( field, entityVersion.getEntityId(), 
entityVersion.getEntityVersion() );
 
+            if(logger.isTraceEnabled()){
+                logger.trace("Putting unique value [{}={}] into result set 
with entity id [{}] and entity version [{}]",
+                    field.getName(), field.getValue().toString(),
+                    entityVersion.getEntityId(),
+                    entityVersion.getEntityVersion());
+            }
+
             uniqueValueSet.addValue( uniqueValue );
         }
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerIT.java
----------------------------------------------------------------------
diff --git 
a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerIT.java
 
b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerIT.java
index 115be99..10c7eb7 100644
--- 
a/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerIT.java
+++ 
b/stack/corepersistence/collection/src/test/java/org/apache/usergrid/persistence/collection/EntityCollectionManagerIT.java
@@ -20,7 +20,6 @@ package org.apache.usergrid.persistence.collection;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 
@@ -118,27 +117,49 @@ public class EntityCollectionManagerIT {
 
         EntityCollectionManager manager = factory.createCollectionManager( 
context );
 
-        {
-            Entity newEntity = new Entity( new SimpleId( "test" ) );
-            newEntity.setField( new IntegerField( "count", 5, true ) );
+        Entity entity = new Entity( new SimpleId( "test" ) );
+        entity.setField( new IntegerField( "count", 5, true ) );
+
+        Observable<Entity> firstWrite = manager.write( entity );
+
+        Entity newEntity = null;
+        Entity firstReturned = null;
+
+        for(int i=0; i<500; i++){
 
-            Observable<Entity> observable = manager.write( newEntity );
-            Entity returned = observable.toBlocking().lastOrDefault( null );
-        }
 
-        {
-            try {
-                Entity newEntity = new Entity( new SimpleId( "test" ) );
-                newEntity.setField( new IntegerField( "count", 5, true ) );
-
-                manager.write( newEntity ).toBlocking().last();
-                fail( "Write should have thrown an exception" );
-            }
-            catch ( Exception ex ) {
-                WriteUniqueVerifyException e = ( WriteUniqueVerifyException ) 
ex;
-                assertEquals( 1, e.getVioliations().size() );
-            }
+            firstReturned = firstWrite.toBlocking().lastOrDefault( null );
+
         }
+
+//        try {
+//            //newEntity = new Entity( new SimpleId( "test" ) );
+//            //newEntity.setField( new IntegerField( "count", 5, true ) );
+//
+//            Observable<Entity> secondWrite = manager.write( entity );
+//            secondReturned = secondWrite.toBlocking().lastOrDefault( null );
+//
+//            //fail( "Write should have thrown an exception" );
+//        }
+//        catch ( Exception ex ) {
+//            WriteUniqueVerifyException e = ( WriteUniqueVerifyException ) ex;
+//            assertEquals( 1, e.getVioliations().size() );
+//        }
+
+        // try fetching the original one again
+
+        assertEquals(entity.getId().getUuid(), 
firstReturned.getId().getUuid());
+        assertEquals(entity.getVersion(), firstReturned.getVersion());
+
+
+        //assertEquals(newEntity.getId().getUuid(), 
secondReturned.getId().getUuid());
+        //assertEquals(newEntity.getVersion(), secondReturned.getVersion());
+
+
+
+
+
+
     }
 
 
@@ -737,7 +758,7 @@ public class EntityCollectionManagerIT {
         assertNotNull( "Version was assigned", createReturned.getVersion() );
 
         FieldSet fieldResults =
-            manager.getEntitiesFromFields( newEntity.getId().getType(), 
Arrays.<Field>asList( expectedInteger ) )
+            manager.getEntitiesFromFields( newEntity.getId().getType(), 
Arrays.<Field>asList( expectedInteger ), false)
                    .toBlocking().last();
 
         assertEquals( 1, fieldResults.size() );
@@ -754,7 +775,7 @@ public class EntityCollectionManagerIT {
 
         //try to load via the unique field, should have triggered repair
         final FieldSet results =
-            manager.getEntitiesFromFields( newEntity.getId().getType(), 
Arrays.<Field>asList( expectedInteger ) )
+            manager.getEntitiesFromFields( newEntity.getId().getType(), 
Arrays.<Field>asList( expectedInteger ), false)
                    .toBlocking().last();
 
 

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
----------------------------------------------------------------------
diff --git 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
index c5473cf..7b9e230 100644
--- 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
+++ 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractCollectionService.java
@@ -85,7 +85,7 @@ public class AbstractCollectionService extends 
AbstractService {
             nameProperty = "name";
         }
 
-        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name );
+        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name, 
true);
         if ( entity != null ) {
             entity = importEntity( request, entity );
         }
@@ -282,7 +282,7 @@ public class AbstractCollectionService extends 
AbstractService {
         }
 
        // EntityRef ref = em.getAlias( getEntityType(), name );
-        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name );
+        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name, 
true);
         if ( entity == null ) {
             // null entity ref means we tried to put a non-existing entity
             // before we create a new entity for it, we should check for 
permission
@@ -477,7 +477,7 @@ public class AbstractCollectionService extends 
AbstractService {
             return super.postItemByName( context, name );
         }
 
-        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name );
+        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name, 
true);
         if ( entity == null ) {
             throw new ServiceResourceNotFoundException( context );
         }
@@ -531,7 +531,7 @@ public class AbstractCollectionService extends 
AbstractService {
             return getItemByName( context, name );
         }
 
-        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name );
+        Entity entity = em.getUniqueEntityFromAlias( getEntityType(), name, 
true);
         if ( entity == null ) {
             throw new ServiceResourceNotFoundException( context );
         }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
----------------------------------------------------------------------
diff --git 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
index 395f2d4..5f7ca6b 100644
--- 
a/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
+++ 
b/stack/services/src/main/java/org/apache/usergrid/services/AbstractConnectionsService.java
@@ -271,7 +271,7 @@ public class AbstractConnectionsService extends 
AbstractService {
 
             //TODO T.N. USERGRID-1919 actually validate this is connected
 
-            Entity entity = em.getUniqueEntityFromAlias( 
query.getEntityType(), name );
+            Entity entity = em.getUniqueEntityFromAlias( 
query.getEntityType(), name, true);
             if ( entity == null ) {
                 return null;
             }
@@ -372,7 +372,7 @@ public class AbstractConnectionsService extends 
AbstractService {
             if ( query.containsSingleNameOrEmailIdentifier() ) {
                 String name = query.getSingleNameOrEmailIdentifier();
 
-                entity = em.getUniqueEntityFromAlias( query.getEntityType(), 
name );
+                entity = em.getUniqueEntityFromAlias( query.getEntityType(), 
name, true);
                 if ( entity == null ) {
                     throw new ServiceResourceNotFoundException( context );
                 }
@@ -529,7 +529,7 @@ public class AbstractConnectionsService extends 
AbstractService {
                 nameProperty = "name";
             }
 
-            Entity entity = em.getUniqueEntityFromAlias( 
query.getEntityType(), name );
+            Entity entity = em.getUniqueEntityFromAlias( 
query.getEntityType(), name, true);
             if ( entity == null ) {
                 throw new ServiceResourceNotFoundException( context );
             }

http://git-wip-us.apache.org/repos/asf/usergrid/blob/06f77d7b/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
----------------------------------------------------------------------
diff --git 
a/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java 
b/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
new file mode 100644
index 0000000..f884a1d
--- /dev/null
+++ 
b/stack/tools/src/main/java/org/apache/usergrid/tools/UniqueValueScanner.java
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.tools;
+
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.UUID;
+
+import com.google.common.base.Optional;
+import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
+import com.netflix.astyanax.model.Column;
+import com.netflix.astyanax.util.RangeBuilder;
+import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.persistence.EntityManager;
+import org.apache.usergrid.persistence.collection.MvccEntity;
+import 
org.apache.usergrid.persistence.collection.serialization.MvccEntitySerializationStrategy;
+import 
org.apache.usergrid.persistence.collection.serialization.UniqueValueSerializationStrategy;
+import org.apache.usergrid.persistence.collection.serialization.UniqueValueSet;
+import org.apache.usergrid.persistence.collection.serialization.impl.*;
+import org.apache.usergrid.persistence.core.scope.ApplicationScopeImpl;
+import org.apache.usergrid.persistence.model.entity.SimpleId;
+import org.apache.usergrid.persistence.model.field.StringField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.Options;
+
+
+import org.apache.usergrid.persistence.core.astyanax.MultiTenantColumnFamily;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKey;
+import org.apache.usergrid.persistence.core.astyanax.ScopedRowKeySerializer;
+
+
+
+public class UniqueValueScanner extends ToolBase {
+
+    private static final Logger logger = LoggerFactory.getLogger( 
UniqueValueScanner.class );
+
+    private static final String APPLICATION_ARG = "app";
+
+    private static final String ENTITY_TYPE_ARG = "entityType";
+
+    private static final String ENTITY_NAME_ARG = "entityName";
+
+
+    //copied shamelessly from unique value serialization strat.
+    private static final ScopedRowKeySerializer<TypeField> ROW_KEY_SER =
+        new ScopedRowKeySerializer<>( UniqueTypeFieldRowKeySerializer.get() );
+
+
+    private final EntityVersionSerializer ENTITY_VERSION_SER = new 
EntityVersionSerializer();
+
+    private final MultiTenantColumnFamily<ScopedRowKey<TypeField>, 
EntityVersion> CF_UNIQUE_VALUES =
+        new MultiTenantColumnFamily<>( "Unique_Values_V2", ROW_KEY_SER, 
ENTITY_VERSION_SER );
+
+    private com.netflix.astyanax.Keyspace keyspace;
+
+    private MvccEntitySerializationStrategy mvccEntitySerializationStrategy;
+
+    private UniqueValueSerializationStrategy uniqueValueSerializationStrategy;
+
+    private EntityManager em;
+
+    @Override
+    @SuppressWarnings( "static-access" )
+    public Options createOptions() {
+
+
+        Options options = super.createOptions();
+
+
+        Option appOption = OptionBuilder.withArgName( APPLICATION_ARG 
).hasArg().isRequired( true )
+            .withDescription( "application id" ).create( APPLICATION_ARG );
+
+
+        options.addOption( appOption );
+
+        Option collectionOption =
+            OptionBuilder.withArgName(ENTITY_TYPE_ARG).hasArg().isRequired( 
true ).withDescription( "collection name" )
+                .create(ENTITY_TYPE_ARG);
+
+        options.addOption( collectionOption );
+
+        Option specificEntityNameOption =
+            OptionBuilder.withArgName(ENTITY_NAME_ARG).hasArg().isRequired( 
true ).withDescription( "specific entity name" )
+                .create(ENTITY_NAME_ARG);
+
+        options.addOption( specificEntityNameOption );
+
+
+        return options;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see
+     * 
org.apache.usergrid.tools.ToolBase#runTool(org.apache.commons.cli.CommandLine)
+     */
+    @Override
+    public void runTool( CommandLine line ) throws Exception {
+
+        startSpring();
+
+        UUID appToFilter = null;
+        if (!line.getOptionValue(APPLICATION_ARG).isEmpty()) {
+            appToFilter = 
UUID.fromString(line.getOptionValue(APPLICATION_ARG));
+        }
+
+
+        logger.info("Starting entity unique scanner");
+
+        keyspace = injector.getInstance(com.netflix.astyanax.Keyspace.class);
+        mvccEntitySerializationStrategy = 
injector.getInstance(MvccEntitySerializationStrategy.class);
+        uniqueValueSerializationStrategy = 
injector.getInstance(UniqueValueSerializationStrategy.class);
+
+
+        String entityType = line.getOptionValue(ENTITY_TYPE_ARG);
+        String entityName = line.getOptionValue(ENTITY_NAME_ARG);
+
+        if (entityName != null && !entityName.isEmpty()) {
+
+            if(appToFilter == null){
+                throw new RuntimeException("Cannot execute UniqueValueScanner 
with specific entity without the " +
+                    "application UUID for which the entity should exist.");
+            }
+
+            if(entityType == null){
+                throw new RuntimeException("Cannot execute UniqueValueScanner 
without the entity type (singular " +
+                    "collection name).");
+            }
+
+            //do stuff
+            UniqueValueSet uniqueValueSet = 
uniqueValueSerializationStrategy.load(
+                new ApplicationScopeImpl( new SimpleId(appToFilter, 
"application" ) ),
+                entityType,
+                Collections.singletonList(new StringField( "name", entityName) 
));
+
+            logger.info("Returned unique value set from serialization load = 
{}", uniqueValueSet);
+
+        } else {
+
+            // scan through all unique values and log some info
+
+            Iterator<com.netflix.astyanax.model.Row<ScopedRowKey<TypeField>, 
EntityVersion>> rows = null;
+            try {
+
+                rows = keyspace.prepareQuery(CF_UNIQUE_VALUES)
+                    .getAllRows()
+                    .withColumnRange(new RangeBuilder().build())
+                    .execute().getResult().iterator();
+
+            } catch (ConnectionException e) {
+
+            }
+
+
+            UUID finalAppToFilter = appToFilter;
+            rows.forEachRemaining(row -> {
+
+                String fieldName = row.getKey().getKey().getField().getName();
+                String scopeType = row.getKey().getScope().getType();
+                UUID scopeUUID = row.getKey().getScope().getUuid();
+
+                if (!fieldName.equalsIgnoreCase("name") ||
+                    (finalAppToFilter != null && 
!finalAppToFilter.equals(scopeUUID))
+                    ) {
+                    // do nothing
+
+                } else {
+
+                    if (em == null && finalAppToFilter.equals(scopeUUID)) {
+                        em = emf.getEntityManager(scopeUUID);
+                    }
+
+                    Iterator<Column<EntityVersion>> columns = 
row.getColumns().iterator();
+                    columns.forEachRemaining(column -> {
+
+                        EntityVersion entityVersion = column.getName();
+
+                        if (entityType != null &&
+                            
entityVersion.getEntityId().getType().equalsIgnoreCase(entityType)
+                            ) {
+
+                            String fieldValue = 
row.getKey().getKey().getField().getValue().toString();
+
+                            logger.trace(
+                                scopeType + ": " + scopeUUID + ", " +
+                                    fieldName + ": " + fieldValue + ", " +
+                                    "entity type: " + 
entityVersion.getEntityId().getType() + ", " +
+                                    "entity uuid: " + 
entityVersion.getEntityId().getUuid()
+                            );
+
+
+                            Entity entity = 
em.getUniqueEntityFromAlias(entityType, fieldValue, false);
+
+//                       Optional<MvccEntity> entity = 
mvccEntitySerializationStrategy.
+//                            load(new ApplicationScopeImpl(new 
SimpleId(scopeUUID, scopeType)), entityVersion.getEntityId());
+//
+//                        if(!entity.isPresent()){
+
+                            if (entity == null) {
+
+                                logger.error("{}: {}. Entity with type=[{}],  
name=[{}], and uuid=[{}] has a unique value entry " +
+                                        "but cannot be loaded from Mvcc entity 
serialization",
+                                    scopeType,
+                                    scopeUUID,
+                                    entityVersion.getEntityId().getType(),
+                                    fieldValue,
+                                    entityVersion.getEntityId().getUuid());
+                            }
+
+                        } else {
+                            // do nothing
+                        }
+
+
+                    });
+                }
+
+
+            });
+
+        }
+    }
+}

Reply via email to