You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2015/07/10 15:37:20 UTC

[14/50] [abbrv] incubator-usergrid git commit: Add organization export to ExportAdmins tool and organization import to ImportAdmins tool.

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java b/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
index 5b77534..8561300 100644
--- a/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
+++ b/stack/services/src/main/java/org/apache/usergrid/management/cassandra/ManagementServiceImpl.java
@@ -496,7 +496,7 @@ public class ManagementServiceImpl implements ManagementService {
                 user = createAdminUserInternal( username, name, email, password, activated, disabled, userProperties );
             }
 
-            organization = createOrganizationInternal( organizationName, user, true, organizationProperties );
+            organization = createOrganizationInternal( null, organizationName, user, true, organizationProperties );
         }
         finally {
             emailLock.unlock();
@@ -508,14 +508,16 @@ public class ManagementServiceImpl implements ManagementService {
     }
 
 
-    private OrganizationInfo createOrganizationInternal( String organizationName, UserInfo user, boolean activated )
-            throws Exception {
-        return createOrganizationInternal( organizationName, user, activated, null );
+    private OrganizationInfo createOrganizationInternal(
+            UUID orgUuid, String organizationName, UserInfo user, boolean activated) throws Exception {
+        return createOrganizationInternal( orgUuid, organizationName, user, activated, null );
     }
 
 
-    private OrganizationInfo createOrganizationInternal( String organizationName, UserInfo user, boolean activated,
-                                                         Map<String, Object> properties ) throws Exception {
+    private OrganizationInfo createOrganizationInternal(
+            UUID orgUuid, String organizationName, UserInfo user, boolean activated,
+            Map<String, Object> properties ) throws Exception {
+
         if ( ( organizationName == null ) || ( user == null ) ) {
             return null;
         }
@@ -524,7 +526,13 @@ public class ManagementServiceImpl implements ManagementService {
 
         Group organizationEntity = new Group();
         organizationEntity.setPath( organizationName );
-        organizationEntity = em.create( organizationEntity );
+
+        if ( orgUuid == null ) {
+            organizationEntity = em.create( organizationEntity );
+        } else {
+            em.create( orgUuid, Group.ENTITY_TYPE, organizationEntity.getProperties() );
+            organizationEntity = em.get( orgUuid, Group.class );
+        }
 
         em.addToCollection( organizationEntity, "users", new SimpleEntityRef( User.ENTITY_TYPE, user.getUuid() ) );
 
@@ -536,20 +544,29 @@ public class ManagementServiceImpl implements ManagementService {
                 new OrganizationInfo( organizationEntity.getUuid(), organizationName, properties );
         updateOrganization( organization );
 
-        logger.info( "createOrganizationInternal: {}", organizationName );
-        postOrganizationActivity( organization.getUuid(), user, "create", organizationEntity, "Organization",
-                organization.getName(),
-                "<a href=\"mailto:" + user.getEmail() + "\">" + user.getName() + " (" + user.getEmail()
-                        + ")</a> created a new organization account named " + organizationName, null );
+        if ( orgUuid == null ) { // no import ID specified, so do the activation email flow stuff
 
-        startOrganizationActivationFlow( organization );
+            logger.info( "createOrganizationInternal: {}", organizationName );
+            postOrganizationActivity( organization.getUuid(), user, "create", organizationEntity, "Organization",
+                    organization.getName(),
+                    "<a href=\"mailto:" + user.getEmail() + "\">" + user.getName() + " (" + user.getEmail()
+                            + ")</a> created a new organization account named " + organizationName, null );
+
+            startOrganizationActivationFlow( organization );
+        }
 
         return organization;
     }
 
 
     @Override
-    public OrganizationInfo createOrganization( String organizationName, UserInfo user, boolean activated )
+    public OrganizationInfo createOrganization(String organizationName, UserInfo user, boolean activated)
+            throws Exception {
+        return createOrganization( organizationName, user, activated );
+    }
+
+    @Override
+    public OrganizationInfo createOrganization(UUID orgUuid, String organizationName, UserInfo user, boolean activated)
             throws Exception {
 
         if ( ( organizationName == null ) || ( user == null ) ) {
@@ -563,7 +580,7 @@ public class ManagementServiceImpl implements ManagementService {
         }
         try {
             groupLock.lock();
-            return createOrganizationInternal( organizationName, user, activated );
+            return createOrganizationInternal( orgUuid, organizationName, user, activated );
         }
         finally {
             groupLock.unlock();

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/pom.xml
----------------------------------------------------------------------
diff --git a/stack/tools/pom.xml b/stack/tools/pom.xml
index 0fac833..77fcee4 100644
--- a/stack/tools/pom.xml
+++ b/stack/tools/pom.xml
@@ -35,7 +35,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-javadoc-plugin</artifactId>
-        <version>2.7</version>
+        <version>2.9.1</version>
       </plugin>
     </plugins>
   </reporting>
@@ -233,5 +233,21 @@
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
     </dependency>
+
+    <dependency>
+      <groupId>org.apache.usergrid</groupId>
+      <artifactId>usergrid-test-utils</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.usergrid</groupId>
+      <artifactId>usergrid-services</artifactId>
+      <classifier>tests</classifier>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
   </dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/main/java/org/apache/usergrid/tools/ExportAdmins.java
----------------------------------------------------------------------
diff --git a/stack/tools/src/main/java/org/apache/usergrid/tools/ExportAdmins.java b/stack/tools/src/main/java/org/apache/usergrid/tools/ExportAdmins.java
index fe2752f..8831b89 100644
--- a/stack/tools/src/main/java/org/apache/usergrid/tools/ExportAdmins.java
+++ b/stack/tools/src/main/java/org/apache/usergrid/tools/ExportAdmins.java
@@ -1,6 +1,3 @@
-/**
- * Created by ApigeeCorporation on 4/9/15.
- */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -26,6 +23,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
+import com.google.common.collect.BiMap;
 import org.codehaus.jackson.JsonGenerator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,7 +37,6 @@ import org.apache.usergrid.persistence.Query;
 import org.apache.usergrid.persistence.Results;
 import org.apache.usergrid.persistence.Results.Level;
 import org.apache.usergrid.persistence.cassandra.CassandraService;
-import org.apache.usergrid.utils.JsonUtils;
 
 
 /**
@@ -47,8 +44,10 @@ import org.apache.usergrid.utils.JsonUtils;
  */
 public class ExportAdmins extends ExportingToolBase {
 
-    static final Logger logger = LoggerFactory.getLogger( Export.class );
+    static final Logger logger = LoggerFactory.getLogger( ExportAdmins.class );
 
+    public static final String ADMIN_USERS_PREFIX = "admin-users";
+    public static final String ADMIN_USER_METADATA_PREFIX = "admin-user-metadata";
 
     @Override
     public void runTool( CommandLine line ) throws Exception {
@@ -61,30 +60,29 @@ public class ExportAdmins extends ExportingToolBase {
         outputDir = createOutputParentDir();
         logger.info( "Export directory: " + outputDir.getAbsolutePath() );
 
-        exportApplicationsForOrg( null );
+        exportAdminUsers();
     }
 
 
-    private void exportApplicationsForOrg( Map.Entry<UUID, String> organization ) throws Exception {
+    private void exportAdminUsers() throws Exception {
+
+        int count = 0;
 
         EntityManager em = emf.getEntityManager( CassandraService.MANAGEMENT_APPLICATION_ID );
 
-        // Get the JSon serializer.
-        JsonGenerator jg = getJsonGenerator( createOutputFile( "application", em.getApplication().getName() ) );
+        // write one JSON file for management application users
 
-        jg.writeStartArray();
+        JsonGenerator usersFile =
+                getJsonGenerator( createOutputFile( ADMIN_USERS_PREFIX, em.getApplication().getName() ) );
+        usersFile.writeStartArray();
 
-        // Create a GENERATOR for the application collections.
-        JsonGenerator collectionsJg =
-                getJsonGenerator( createOutputFile( "collections", em.getApplication().getName() ) );
-        collectionsJg.writeStartObject();
+        // write one JSON file for metadata: collections, connections and dictionaries of those users
 
-        Map<String, Object> metadata = em.getApplicationCollectionMetadata();
-        echo( JsonUtils.mapToFormattedJsonString( metadata ) );
+        JsonGenerator metadataFile =
+                getJsonGenerator( createOutputFile( ADMIN_USER_METADATA_PREFIX, em.getApplication().getName() ) );
+        metadataFile.writeStartObject();
 
-        // Loop through the collections. This is the only way to loop
-        // through the entities in the application (former namespace).
-        // for ( String collectionName : metadata.keySet() ) {
+        // query for and loop through all users in management application
 
         Query query = new Query();
         query.setLimit( MAX_ENTITY_FETCH );
@@ -95,33 +93,37 @@ public class ExportAdmins extends ExportingToolBase {
         while ( entities.size() > 0 ) {
 
             for ( Entity entity : entities ) {
-                // Export the entity first and later the collections for
-                // this entity.
-                jg.writeObject( entity );
+
+                // write user to application file
+                usersFile.writeObject( entity );
                 echo( entity );
 
-                saveCollectionMembers( collectionsJg, em, null, entity );
+                // write user's collections, connections, etc. to collections file
+                saveEntityMetadata( metadataFile, em, null, entity );
+
+                logger.debug("Exported user {}", entity.getProperty( "email" ));
+
+                count++;
+                if ( count % 1000 == 0 ) {
+                    logger.info("Exported {} admin users", count);
+                }
+
             }
 
-            //we're done
             if ( entities.getCursor() == null ) {
                 break;
             }
-
             query.setCursor( entities.getCursor() );
-
             entities = em.searchCollection( em.getApplicationRef(), "users", query );
         }
-        //}
 
-        // Close writer for the collections for this application.
-        collectionsJg.writeEndObject();
-        collectionsJg.close();
+        metadataFile.writeEndObject();
+        metadataFile.close();
 
-        // Close writer and file for this application.
-        jg.writeEndArray();
-        jg.close();
-        // }
+        usersFile.writeEndArray();
+        usersFile.close();
+
+        logger.info("Exported total of {} admin users", count);
     }
 
 
@@ -132,8 +134,20 @@ public class ExportAdmins extends ExportingToolBase {
      * @param application Application name
      * @param entity entity
      */
-    private void saveCollectionMembers( JsonGenerator jg, EntityManager em, String application, Entity entity )
-            throws Exception {
+    private void saveEntityMetadata(
+            JsonGenerator jg, EntityManager em, String application, Entity entity) throws Exception {
+
+        saveCollections( jg, em, entity );
+        saveConnections( entity, em, jg );
+        saveOrganizations( entity, em, jg );
+        saveDictionaries( entity, em, jg );
+
+        // End the object if it was Started
+        jg.writeEndObject();
+    }
+
+
+    private void saveCollections(JsonGenerator jg, EntityManager em, Entity entity) throws Exception {
 
         Set<String> collections = em.getCollections( entity );
 
@@ -164,17 +178,9 @@ public class ExportAdmins extends ExportingToolBase {
             // End collection array.
             jg.writeEndArray();
         }
-
-        // Write connections
-        saveConnections( entity, em, jg );
-
-        // Write dictionaries
-        saveDictionaries( entity, em, jg );
-
-        // End the object if it was Started
-        jg.writeEndObject();
     }
 
+
     /**
      * Persists the connection for this entity.
      */
@@ -207,8 +213,9 @@ public class ExportAdmins extends ExportingToolBase {
         jg.writeEndObject();
     }
 
+
     /**
-     * Persists the connection for this entity.
+     * Persists the outgoing connections for this entity.
      */
     private void saveConnections( Entity entity, EntityManager em, JsonGenerator jg ) throws Exception {
 
@@ -232,5 +239,34 @@ public class ExportAdmins extends ExportingToolBase {
         }
         jg.writeEndObject();
     }
+
+
+    /**
+     * Persists the incoming connections for this entity.
+     */
+    private void saveOrganizations(Entity entity, EntityManager em, JsonGenerator jg) throws Exception {
+
+        final BiMap<UUID, String> orgs = managementService.getOrganizationsForAdminUser( entity.getUuid() );
+
+        jg.writeFieldName( "organizations" );
+
+        jg.writeStartArray();
+
+        for ( UUID uuid : orgs.keySet() ) {
+
+             jg.writeStartObject();
+
+             jg.writeFieldName( "uuid" );
+             jg.writeObject( uuid );
+
+             jg.writeFieldName( "name" );
+             jg.writeObject( orgs.get( uuid ) );
+
+             jg.writeEndObject();
+        }
+
+        jg.writeEndArray();
+    }
+
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/main/java/org/apache/usergrid/tools/ImportAdmins.java
----------------------------------------------------------------------
diff --git a/stack/tools/src/main/java/org/apache/usergrid/tools/ImportAdmins.java b/stack/tools/src/main/java/org/apache/usergrid/tools/ImportAdmins.java
index 76b2343..bf0a2e4 100644
--- a/stack/tools/src/main/java/org/apache/usergrid/tools/ImportAdmins.java
+++ b/stack/tools/src/main/java/org/apache/usergrid/tools/ImportAdmins.java
@@ -17,33 +17,29 @@
 package org.apache.usergrid.tools;
 
 
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.ObjectMapper;
-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.commons.io.filefilter.PrefixFileFilter;
-
 import org.apache.usergrid.management.OrganizationInfo;
-import org.apache.usergrid.persistence.Entity;
+import org.apache.usergrid.management.UserInfo;
 import org.apache.usergrid.persistence.EntityManager;
 import org.apache.usergrid.persistence.EntityRef;
-import org.apache.usergrid.persistence.entities.Application;
+import org.apache.usergrid.persistence.entities.User;
 import org.apache.usergrid.persistence.exceptions.DuplicateUniquePropertyExistsException;
-import org.apache.usergrid.utils.JsonUtils;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 
 import static org.apache.usergrid.persistence.Schema.PROPERTY_TYPE;
 import static org.apache.usergrid.persistence.Schema.PROPERTY_UUID;
@@ -75,14 +71,15 @@ public class ImportAdmins extends ToolBase {
     @SuppressWarnings( "static-access" )
     public Options createOptions() {
 
-        Option hostOption =
-                OptionBuilder.withArgName( "host" ).hasArg().withDescription( "Cassandra host" ).create( "host" );
+        Option hostOption = OptionBuilder.withArgName( "host" )
+                .hasArg().withDescription( "Cassandra host" ).create( "host" );
 
-        Option inputDir = OptionBuilder.hasArg().withDescription( "input directory -inputDir" ).create( INPUT_DIR );
+        Option inputDir = OptionBuilder
+                .hasArg().withDescription( "input directory -inputDir" ).create( INPUT_DIR );
 
-        Option verbose =
-                OptionBuilder.withDescription( "Print on the console an echo of the content written to the file" )
-                             .create( VERBOSE );
+        Option verbose = OptionBuilder
+                .withDescription( "Print on the console an echo of the content written to the file" )
+                .create( VERBOSE );
 
         Options options = new Options();
         options.addOption( hostOption );
@@ -95,118 +92,101 @@ public class ImportAdmins extends ToolBase {
 
     @Override
     public void runTool( CommandLine line ) throws Exception {
+
         startSpring();
 
         setVerbose( line );
 
         openImportDirectory( line );
 
-        importApplications();
-
-        importCollections();
+        importAdminUsers();
 
-        //forces the counters to flush
-        logger.info( "Sleeping 35 seconds for batcher" );
+        importMetadata();
 
-        Thread.sleep( 35000 );
+        // forces the counters to flush
+//        logger.info( "Sleeping 35 seconds for batcher" );
+//        Thread.sleep( 35000 );
     }
 
 
     /**
-     * Import applications
+     * Import admin users.
      */
-    private void importApplications() throws Exception {
-        String[] nanemspaceFileNames = importDir.list( new PrefixFileFilter( "application." ) );
-        logger.info( "Applications to read: " + nanemspaceFileNames.length );
+    private void importAdminUsers() throws Exception {
+        String[] fileNames = importDir.list( new PrefixFileFilter( ExportAdmins.ADMIN_USERS_PREFIX + "." ) );
+        logger.info( "Applications to read: " + fileNames.length );
 
         //this fails on the second run of the applications find out why.
-        for ( String applicationName : nanemspaceFileNames ) {
+        for ( String fileName : fileNames ) {
             try {
-                importApplication( applicationName );
+                importAdminUsers( fileName );
             }
             catch ( Exception e ) {
-                logger.warn( "Unable to import application: " + applicationName, e );
+                logger.warn( "Unable to import application: " + fileName, e );
             }
         }
     }
 
 
     /**
-     * Imports a application
+     * Imports admin users.
      *
-     * @param applicationName file name where the application was exported.
+     * @param fileName Name of admin user data file.
      */
-    private void importApplication( String applicationName ) throws Exception {
-        // Open up application file.
-        File applicationFile = new File( importDir, applicationName );
-
-        logger.info( "Loading application file: " + applicationFile.getAbsolutePath() );
-        JsonParser jp = getJsonParserForFile( applicationFile );
-
-        JsonToken token = jp.nextToken();
-        validateStartArray( token );
+    private void importAdminUsers( String fileName ) throws Exception {
 
-        // Move to next object (the application).
-        // The application object is the first object followed by all the
-        // objects in this application.
-        token = jp.nextValue();
-
-        Application application = jp.readValueAs( Application.class );
-
-        UUID appId = MANAGEMENT_APPLICATION_ID;
-
-        EntityManager em = emf.getEntityManager( appId );
-
-        // we now need to remove all roles, they'll be imported again below
-
-        for ( Entry<String, String> entry : em.getRoles().entrySet() ) {
-            em.deleteRole( entry.getKey() );
-        }
+        int count = 0;
 
-        //load all the dictionaries
-        @SuppressWarnings( "unchecked" ) Map<String, Object> dictionaries =
-                ( Map<String, Object> ) application.getMetadata( "dictionaries" );
+        File adminUsersFile = new File( importDir, fileName );
 
-        if ( dictionaries != null ) {
-            EntityManager rootEm = emf.getEntityManager( MANAGEMENT_APPLICATION_ID );
+        logger.info( "----- Loading file: " + adminUsersFile.getAbsolutePath() );
+        JsonParser jp = getJsonParserForFile( adminUsersFile );
 
-            Entity appEntity = rootEm.get( appId );
+        JsonToken token = jp.nextToken();
+        validateStartArray( token );
 
+        EntityManager em = emf.getEntityManager( MANAGEMENT_APPLICATION_ID );
 
-            for ( Entry<String, Object> dictionary : dictionaries.entrySet() ) {
-                @SuppressWarnings( "unchecked" ) Map<Object, Object> value =
-                        ( Map<Object, Object> ) dictionary.getValue();
+        while ( jp.nextValue() != JsonToken.END_ARRAY ) {
 
-                em.addMapToDictionary( appEntity, dictionary.getKey(), value );
-            }
-        }
+            @SuppressWarnings( "unchecked" )
+            Map<String, Object> entityProps = jp.readValueAs( HashMap.class );
 
-        while ( jp.nextValue() != JsonToken.END_ARRAY ) {
-            @SuppressWarnings( "unchecked" ) Map<String, Object> entityProps = jp.readValueAs( HashMap.class );
             // Import/create the entity
             UUID uuid = getId( entityProps );
             String type = getType( entityProps );
 
+
             try {
                 em.create( uuid, type, entityProps );
+
+                logger.debug( "Imported admin user {} {}", uuid, entityProps.get( "username" ) );
+                count++;
+                if ( count % 1000 == 0 ) {
+                    logger.info("Imported {} admin users", count);
+                }
             }
             catch ( DuplicateUniquePropertyExistsException de ) {
-                logger.error( "Unable to create entity.  It appears to be a duplicate", de );
+                logger.warn( "Unable to create entity. It appears to be a duplicate: " +
+                    "id={}, type={}, name={}, username={}",
+                    new Object[] { uuid, type, entityProps.get("name"), entityProps.get("username")});
+                if ( logger.isDebugEnabled() ) {
+                    logger.debug( "Exception" , de );
+                }
                 continue;
             }
 
             if ( em.get( uuid ) == null ) {
-                logger.error( "Holy hell, we wrote an entity and it's missing.  Entity Id was {} and type is {}", uuid,
-                        type );
+                logger.error( "Holy hell, we wrote an entity and it's missing.  " +
+                                "Entity Id was {} and type is {}", uuid, type );
                 System.exit( 1 );
             }
-
-            logger.info( "Counts {}", JsonUtils.mapToFormattedJsonString( em.getApplicationCounters() ) );
-
             echo( entityProps );
         }
 
-        logger.info( "----- End of application:" + application.getName() );
+        logger.info( "----- End: Imported {} admin users from file {}",
+                count, adminUsersFile.getAbsolutePath() );
+
         jp.close();
     }
 
@@ -238,198 +218,181 @@ public class ImportAdmins extends ToolBase {
     /**
      * Import collections. Collections files are named: collections.<application_name>.Timestamp.json
      */
-    private void importCollections() throws Exception {
-        String[] collectionsFileNames = importDir.list( new PrefixFileFilter( "collections." ) );
-        logger.info( "Collections to read: " + collectionsFileNames.length );
+    private void importMetadata() throws Exception {
+
+        String[] fileNames = importDir.list(
+                new PrefixFileFilter( ExportAdmins.ADMIN_USER_METADATA_PREFIX + "." ) );
+        logger.info( "Metadata files to read: " + fileNames.length );
 
-        for ( String collectionName : collectionsFileNames ) {
+        for ( String fileName : fileNames ) {
             try {
-                importCollection( collectionName );
+                importMetadata( fileName );
             }
             catch ( Exception e ) {
-                logger.warn( "Unable to import collection: " + collectionName, e );
+                logger.warn( "Unable to import metadata file: " + fileName, e );
             }
         }
     }
 
 
-    private void importCollection( String collectionFileName ) throws Exception {
-        // Retrieve the namepsace for this collection. It's part of the name
-        String applicationName = getApplicationFromColllection( collectionFileName );
-
-        UUID appId = emf.lookupApplication( applicationName );
-
-        //no org in path, this is a pre public beta so we need to create the new path
-        if ( appId == null && !applicationName.contains( "/" ) ) {
-            String fileName = collectionFileName.replace( "collections", "application" );
-
-            File applicationFile = new File( importDir, fileName );
+    @SuppressWarnings( "unchecked" )
+    private void importMetadata( String fileName ) throws Exception {
 
-            if ( !applicationFile.exists() ) {
-                logger.error( "Could not load application file {} to search for org information",
-                        applicationFile.getAbsolutePath() );
-                return;
-            }
-
-
-            logger.info( "Loading application file: " + applicationFile.getAbsolutePath() );
+        EntityManager em = emf.getEntityManager( MANAGEMENT_APPLICATION_ID );
 
-            JsonParser jp = getJsonParserForFile( applicationFile );
+        File metadataFile = new File( importDir, fileName );
 
-            JsonToken token = jp.nextToken();
-            validateStartArray( token );
+        logger.info( "----- Loading metadata file: " + metadataFile.getAbsolutePath() );
 
-            // Move to next object (the application).
-            // The application object is the first object followed by all the
-            // objects in this application.
-            token = jp.nextValue();
+        JsonParser jp = getJsonParserForFile( metadataFile );
 
-            Application application = jp.readValueAs( Application.class );
+        JsonToken jsonToken = null; // jp.nextToken();// START_OBJECT this is the outer hashmap
 
-            jp.close();
+        int depth = 1;
 
-            @SuppressWarnings( "unchecked" ) String orgName =
-                    ( ( Map<String, String> ) application.getMetadata( "organization" ) ).get( "value" );
+        while ( depth > 0 ) {
 
-            OrganizationInfo info = managementService.getOrganizationByName( orgName );
+            jsonToken = jp.nextToken();
 
-            if ( info == null ) {
-                logger.error( "Could not find org with name {}", orgName );
-                return;
+            if ( jsonToken == null ) {
+                logger.info("token is null, breaking");
+                break;
             }
 
-            applicationName = orgName + "/" + applicationName;
-
-            appId = emf.lookupApplication( applicationName );
-        }
-
-
-        if ( appId == null ) {
-            logger.error( "Unable to find application with name {}.  Skipping collections", appId );
-            return;
-        }
-
-        File collectionFile = new File( importDir, collectionFileName );
-
-        logger.info( "Loading collections file: " + collectionFile.getAbsolutePath() );
-
-        JsonParser jp = getJsonParserForFile( collectionFile );
+            if (jsonToken.equals( JsonToken.START_OBJECT )) {
+                depth++;
+            } else if (jsonToken.equals( JsonToken.END_OBJECT )) {
+                depth--;
+            }
 
-        jp.nextToken(); // START_OBJECT this is the outter hashmap
+            if (jsonToken.equals( JsonToken.FIELD_NAME ) && depth == 2 ) {
 
+                jp.nextToken();
 
-        EntityManager em = emf.getEntityManager( appId );
+                String entityOwnerId = jp.getCurrentName();
+                EntityRef entityRef = em.getRef( UUID.fromString( entityOwnerId ) );
 
-        while ( jp.nextToken() != JsonToken.END_OBJECT ) {
-            try {
-                importEntitysStuff( jp, em );
-            }
-            catch ( NullPointerException nae ) {
-                //consume the read of the value so we can move on to process the next token.
-                jp.readValueAs( JsonNode.class );
+                Map<String, Object> metadata = (Map<String, Object>)jp.readValueAs( Map.class );
+                importEntityMetadata( em, entityRef, metadata );
             }
         }
 
-        logger.info( "----- End of collections -----" );
+        logger.info( "----- End of metadata -----" );
         jp.close();
     }
 
 
     /**
      * Imports the entity's connecting references (collections and connections)
-     *
-     * @param jp JsonPrser pointing to the beginning of the object.
      */
-    private void importEntitysStuff( JsonParser jp, EntityManager em ) throws Exception {
-        // The entity that owns the collections
-        String entityOwnerId = jp.getCurrentName();
-        EntityRef ownerEntityRef = em.getRef( UUID.fromString( entityOwnerId ) );
-
-
-        jp.nextToken(); // start object
-
-        //this is done after getting the next token so that we only capture the JsonNode object
-        // and not the entire file response.
-        if ( ownerEntityRef == null ) {
-            throw new NullPointerException( "Couldn't retrieve entity ref from: " + entityOwnerId );
+    @SuppressWarnings("unchecked")
+    private void importEntityMetadata(
+        EntityManager em, EntityRef entityRef, Map<String, Object> metadata ) throws Exception {
+
+        Map<String, Object> connectionsMap = (Map<String, Object>) metadata.get( "connections" );
+
+        if (connectionsMap != null && !connectionsMap.isEmpty()) {
+            for (String type : connectionsMap.keySet()) {
+                try {
+                    UUID uuid = UUID.fromString( (String) connectionsMap.get( type ) );
+                    EntityRef connectedEntityRef = em.getRef( uuid );
+                    em.createConnection( entityRef, type, connectedEntityRef );
+
+                    logger.debug( "Creating connection from {} type {} target {}",
+                            new Object[]{entityRef, type, connectedEntityRef});
+
+                } catch (Exception e) {
+                    if (logger.isDebugEnabled()) {
+                        logger.error( "Error importing connection of type "
+                                + type + " for user " + entityRef.getUuid(), e );
+                    } else {
+                        logger.error( "Error importing connection of type "
+                                + type + " for user " + entityRef.getUuid() );
+                    }
+                }
+            }
         }
 
-        // Go inside the value after getting the owner entity id.
-        while ( jp.nextToken() != JsonToken.END_OBJECT ) {
-            String collectionName = jp.getCurrentName();
+        Map<String, Object> dictionariesMap = (Map<String, Object>) metadata.get( "dictionaries" );
 
-            if ( collectionName.equals( "connections" ) ) {
+        if (dictionariesMap != null && !dictionariesMap.isEmpty()) {
+            for (String name : dictionariesMap.keySet()) {
+                try {
+                    Map<String, Object> dictionary = (Map<String, Object>) dictionariesMap.get( name );
+                    em.addMapToDictionary( entityRef, name, dictionary );
 
-                jp.nextToken(); // START_OBJECT
-                while ( jp.nextToken() != JsonToken.END_OBJECT ) {
-                    String connectionType = jp.getCurrentName();
+                    logger.debug("Creating dictionary for {} name {} map {}",
+                            new Object[] { entityRef, name, dictionary  });
 
-                    jp.nextToken(); // START_ARRAY
-                    while ( jp.nextToken() != JsonToken.END_ARRAY ) {
-                        String entryId = jp.getText();
-                        EntityRef entryRef = em.getRef( UUID.fromString( entryId ) );
-                        // Store in DB
-                        em.createConnection( ownerEntityRef, connectionType, entryRef );
+                } catch (Exception e) {
+                    if (logger.isDebugEnabled()) {
+                        logger.error( "Error importing dictionary name "
+                                + name + " for user " + entityRef.getUuid(), e );
+                    } else {
+                        logger.error( "Error importing dictionary name "
+                                + name + " for user " + entityRef.getUuid() );
                     }
                 }
             }
-            else if ( collectionName.equals( "dictionaries" ) ) {
+        }
 
-                jp.nextToken(); // START_OBJECT
-                while ( jp.nextToken() != JsonToken.END_OBJECT ) {
+        List<String> collectionsList = (List<String>) metadata.get( "collections" );
+        if (collectionsList != null && !collectionsList.isEmpty()) {
+            for (String name : collectionsList) {
+                try {
+                    UUID uuid = UUID.fromString( (String) connectionsMap.get( name ) );
+                    EntityRef collectedEntityRef = em.getRef( uuid );
+                    em.addToCollection( entityRef, name, collectedEntityRef );
+
+                    logger.debug("Add to collection of {} name {} entity {}",
+                            new Object[] { entityRef, name, collectedEntityRef });
+
+                } catch (Exception e) {
+                    if (logger.isDebugEnabled()) {
+                        logger.error( "Error adding to collection "
+                                + name + " for user " + entityRef.getUuid(), e );
+                    } else {
+                        logger.error( "Error adding to collection "
+                                + name + " for user " + entityRef.getUuid() );
+                    }
+                }
+            }
+        }
 
 
-                    String dictionaryName = jp.getCurrentName();
+        List<Object> organizationsList = (List<Object>) metadata.get( "organizations" );
+        if (organizationsList != null && !organizationsList.isEmpty()) {
 
-                    jp.nextToken();
+            for ( Object orgObject : organizationsList ) {
 
-                    @SuppressWarnings( "unchecked" ) Map<String, Object> dictionary = jp.readValueAs( HashMap.class );
+                Map<String, Object> orgMap = (Map<String, Object>)orgObject;
+                UUID orgUuid = UUID.fromString( (String)orgMap.get("uuid") );
+                String orgName = (String)orgMap.get("name");
 
-                    em.addMapToDictionary( ownerEntityRef, dictionaryName, dictionary );
-                }
-            }
+                User user = em.get( entityRef, User.class );
+                final UserInfo userInfo = managementService.getAdminUserByEmail( user.getEmail() );
 
-            else {
-                // Regular collections
+                // create org only if it does not exist
+                OrganizationInfo orgInfo = managementService.getOrganizationByUuid( orgUuid );
+                if ( orgInfo == null ) {
+                    try {
+                        managementService.createOrganization( orgUuid, orgName, userInfo, false );
+                        orgInfo = managementService.getOrganizationByUuid( orgUuid );
 
-                jp.nextToken(); // START_ARRAY
-                while ( jp.nextToken() != JsonToken.END_ARRAY ) {
-                    String entryId = jp.getText();
-                    EntityRef entryRef = em.getRef( UUID.fromString( entryId ) );
+                        logger.debug( "Created new org {} for user {}",
+                            new Object[]{orgInfo.getName(), user.getEmail()} );
 
-                    // store it
-                    em.addToCollection( ownerEntityRef, collectionName, entryRef );
+                    } catch (DuplicateUniquePropertyExistsException dpee ) {
+                        logger.error("Org {} already exists", orgName );
+                    }
+                } else {
+                    managementService.addAdminUserToOrganization( userInfo, orgInfo, false );
+                    logger.debug( "Added user {} to org {}", new Object[]{user.getEmail(), orgName} );
                 }
             }
         }
     }
 
-    /**
-     * Extract a application name from a collectionsFileName in the way:
-     * collections.<a_name_space_name>.TIMESTAMP.json
-     *
-     * @param collectionFileName
-     *            a collection file name
-     * @return the application name for this collections file name
-     */
-    /**
-     * Extract a application name from a collectionsFileName in the way: collections.<a_name_space_name>.TIMESTAMP.json
-     *
-     * @param collectionFileName a collection file name
-     *
-     * @return the application name for this collections file name
-     */
-    private String getApplicationFromColllection( String collectionFileName ) {
-        int firstDot = collectionFileName.indexOf( "." );
-        int secondDot = collectionFileName.indexOf( ".", firstDot + 1 );
-
-        // The application will be in the subString between the dots.
-
-        String appName = collectionFileName.substring( firstDot + 1, secondDot );
-
-        return appName.replace( PATH_REPLACEMENT, "/" );
-    }
-
 
     /**
      * Open up the import directory based on <code>importDir</code>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/main/java/org/apache/usergrid/tools/ToolBase.java
----------------------------------------------------------------------
diff --git a/stack/tools/src/main/java/org/apache/usergrid/tools/ToolBase.java b/stack/tools/src/main/java/org/apache/usergrid/tools/ToolBase.java
index d0780a6..63187a4 100644
--- a/stack/tools/src/main/java/org/apache/usergrid/tools/ToolBase.java
+++ b/stack/tools/src/main/java/org/apache/usergrid/tools/ToolBase.java
@@ -64,7 +64,7 @@ public abstract class ToolBase {
 
     static final Logger logger = LoggerFactory.getLogger( ToolBase.class );
 
-    protected static final String PATH_REPLACEMENT = "USERGIRD-PATH-BACKSLASH";
+    protected static final String PATH_REPLACEMENT = "-";
 
     protected EmbeddedServerHelper embedded = null;
 
@@ -80,6 +80,10 @@ public abstract class ToolBase {
 
 
     public void startTool( String[] args ) {
+        startTool( args, true );
+    }
+
+    public void startTool( String[] args, boolean exit ) {
         CommandLineParser parser = new GnuParser();
         CommandLine line = null;
         try {
@@ -103,7 +107,9 @@ public abstract class ToolBase {
         catch ( Exception e ) {
             e.printStackTrace();
         }
-        System.exit( 0 );
+        if ( exit ) {
+            System.exit( 0 );
+        }
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/stack/tools/src/main/resources/log4j.properties b/stack/tools/src/main/resources/log4j.properties
index e9c23e5..73ade48 100644
--- a/stack/tools/src/main/resources/log4j.properties
+++ b/stack/tools/src/main/resources/log4j.properties
@@ -26,20 +26,21 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern=%d %p (%t) [%c] - %m%n
 
-log4j.category.org.apache.usergrid.tools=TRACE, stdout
-
-log4j.logger.org.apache.usergrid.persistence.cassandra.DB=WARN, stdout
-log4j.logger.org.apache.usergrid.persistence.cassandra.BATCH=WARN, stdout
-log4j.logger.org.apache.usergrid.persistence.cassandra.EntityManagerFactoryImpl=WARN, stdout
-log4j.logger.org.apache.usergrid.persistence.cassandra.DaoUtils=WARN, stdout
-log4j.logger.org.apache.usergrid.persistence.cassandra.EntityManagerImpl=WARN, stdout
-log4j.logger.org.apache.usergrid.persistence.cassandra.ConnectionRefImpl=WARN, stdout
-log4j.logger.me.prettyprint.cassandra.hector.TimingLogger=WARN, stdout
-log4j.logger.org.apache.usergrid.rest.security.AllowAjaxFilter=WARN, stdout
-log4j.logger.me.prettyprint.hector.api.beans.AbstractComposite=ERROR, stdout
+log4j.logger.org.apache.usergrid.tools=DEBUG
+log4j.logger.org.apache.usergrid.management.cassandra=DEBUB
+
+log4j.logger.org.apache.usergrid.persistence.cassandra.DB=WARN
+log4j.logger.org.apache.usergrid.persistence.cassandra.BATCH=WARN
+log4j.logger.org.apache.usergrid.persistence.cassandra.EntityManagerFactoryImpl=WARN
+log4j.logger.org.apache.usergrid.persistence.cassandra.DaoUtils=WARN
+log4j.logger.org.apache.usergrid.persistence.cassandra.EntityManagerImpl=WARN
+log4j.logger.org.apache.usergrid.persistence.cassandra.ConnectionRefImpl=WARN
+log4j.logger.me.prettyprint.cassandra.hector.TimingLogger=WARN
+log4j.logger.org.apache.usergrid.rest.security.AllowAjaxFilter=WARN
+log4j.logger.me.prettyprint.hector.api.beans.AbstractComposite=ERROR
 #log4j.logger.org.apache.usergrid.locking.singlenode.SingleNodeLockManagerImpl=DEBUG, stdout
 
-log4j.logger.org.apache.usergrid.persistence.hector.CountingMutator=INFO, stdout
+log4j.logger.org.apache.usergrid.persistence.hector.CountingMutator=INFO
 
 #log4j.logger.org.apache.cassandra.service.StorageProxy=DEBUG, stdout
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/test/java/org/apache/usergrid/tools/ExportImportAdminsTest.java
----------------------------------------------------------------------
diff --git a/stack/tools/src/test/java/org/apache/usergrid/tools/ExportImportAdminsTest.java b/stack/tools/src/test/java/org/apache/usergrid/tools/ExportImportAdminsTest.java
new file mode 100644
index 0000000..bab6150
--- /dev/null
+++ b/stack/tools/src/test/java/org/apache/usergrid/tools/ExportImportAdminsTest.java
@@ -0,0 +1,232 @@
+/*
+ * 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 com.google.common.collect.BiMap;
+import com.google.common.io.Files;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.RandomStringUtils;
+import org.apache.usergrid.ServiceITSetup;
+import org.apache.usergrid.ServiceITSetupImpl;
+import org.apache.usergrid.ServiceITSuite;
+import org.apache.usergrid.management.OrganizationInfo;
+import org.apache.usergrid.management.OrganizationOwnerInfo;
+import org.apache.usergrid.management.UserInfo;
+import org.apache.usergrid.utils.UUIDUtils;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.ClassRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import static junit.framework.TestCase.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+
+public class ExportImportAdminsTest {
+    static final Logger logger = LoggerFactory.getLogger( ExportImportAdminsTest.class );
+
+    @ClassRule
+    public static ServiceITSetup setup = new ServiceITSetupImpl( ServiceITSuite.cassandraResource );
+
+    @org.junit.Test
+    public void testExportUserAndOrg() throws Exception {
+
+        // create two orgs each with owning user
+
+        final String random1 = RandomStringUtils.randomAlphanumeric( 10 );
+        final OrganizationOwnerInfo orgOwnerInfo1 = setup.getMgmtSvc().createOwnerAndOrganization(
+                "org_" + random1, "user_" + random1, "user_" + random1,
+                "user_" + random1 + "@example.com", "password" );
+
+        final String random2 = RandomStringUtils.randomAlphanumeric( 10 );
+        final OrganizationOwnerInfo orgOwnerInfo2 = setup.getMgmtSvc().createOwnerAndOrganization(
+                "org_" + random2, "user_" + random2, "user_" + random2,
+                "user_" + random2 + "@example.com", "password" );
+
+        // Add user1 to org2
+
+        setup.getMgmtSvc().addAdminUserToOrganization(
+                orgOwnerInfo1.getOwner(), orgOwnerInfo2.getOrganization(), false );
+
+        setup.getMgmtSvc().addAdminUserToOrganization(
+                orgOwnerInfo1.getOwner(), orgOwnerInfo2.getOrganization(), false );
+
+        // export to file
+
+        String directoryName = "./target/export" + RandomStringUtils.randomAlphanumeric(10);
+
+        ExportAdmins exportAdmins = new ExportAdmins();
+        exportAdmins.startTool( new String[] {
+            "-host", "localhost:" + ServiceITSuite.cassandraResource.getRpcPort(),
+            "-outputDir", directoryName
+        }, false );
+
+        // read, parse and verify files
+
+        // first, the admin users file
+
+        File directory = new File( directoryName );
+        String[] adminUsersFileNames = directory.list( new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return name.startsWith("admin-users.");
+            }
+        });
+
+        // only one. read it into a map
+
+        File adminUsersFile = new File(
+                directory.getAbsolutePath() + File.separator + adminUsersFileNames[0] );
+
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode node = mapper.readTree( adminUsersFile );
+        assertTrue( node.isArray() );
+
+        // does file contain our two admin users?
+
+        Set<String> usernames = new HashSet<String>();
+        for ( int i=0; i<node.size(); i++) {
+            JsonNode jsonNode = node.get( i );
+            usernames.add( jsonNode.get("username").asText() );
+        }
+        assertTrue( usernames.contains( "user_" + random1 ));
+        assertTrue( usernames.contains( "user_" + random2 ));
+
+        // second, the metadata file
+
+        String[] metadataFileNames = directory.list( new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                return name.startsWith("admin-user-metadata.");
+            }
+        });
+
+        // only one, read it into a map
+
+        File metadataFile = new File(
+                directory.getAbsolutePath() + File.separator + metadataFileNames[0] );
+
+        mapper = new ObjectMapper();
+        node = mapper.readTree( metadataFile );
+        assertTrue( node.isObject() );
+
+        // do users belong to correct orgs
+
+        JsonNode user1node = node.findValue( orgOwnerInfo1.getOwner().getUuid().toString() );
+        JsonNode orgs1 = user1node.findValue( "organizations");
+        assertEquals( 2, orgs1.size() );
+
+        JsonNode user2node = node.findValue( orgOwnerInfo2.getOwner().getUuid().toString() );
+        JsonNode orgs2 = user2node.findValue( "organizations");
+        assertEquals( 1, orgs2.size() );
+    }
+
+
+    @org.junit.Test
+    public void testImportAdminUsersAndOrgs() throws Exception {
+
+        // first: generate the data file with unique user and org IDs and names
+
+        String rand1 = RandomStringUtils.randomAlphanumeric( 10 );
+        String rand2 = RandomStringUtils.randomAlphanumeric( 10 );
+
+        UUID user_uuid_1 = UUIDUtils.newTimeUUID();
+        UUID user_uuid_2 = UUIDUtils.newTimeUUID();
+
+        UUID org_uuid_1  = UUIDUtils.newTimeUUID();
+        UUID org_uuid_2  = UUIDUtils.newTimeUUID();
+
+        String user_name_1 = "user_" + rand1;
+        String user_name_2 = "user_" + rand2;
+
+        String org_name_1  = "org_"  + rand1;
+        String org_name_2  = "org_"  + rand2;
+
+        // loop through resource files with prefix 'admin-user' those are the data file templates
+
+        File resourcesDir = new File("./target/test-classes");
+        String[] fileNames = resourcesDir.list();
+        File tempDir = Files.createTempDir();
+
+        for ( String fileName : fileNames ) {
+
+            if ( fileName.startsWith("admin-user")) {
+
+                // substitute our new unique IDs and names and write data files to temp directory
+
+                String fileContent = IOUtils.toString( new FileInputStream(
+                        resourcesDir.getAbsolutePath() + File.separator + fileName ) );
+
+                fileContent = fileContent.replaceAll( "USER_UUID_1", user_uuid_1.toString() );
+                fileContent = fileContent.replaceAll( "USER_UUID_2", user_uuid_2.toString() );
+
+                fileContent = fileContent.replaceAll( "ORG_UUID_1",  org_uuid_1.toString() );
+                fileContent = fileContent.replaceAll( "ORG_UUID_2",  org_uuid_2.toString() );
+
+                fileContent = fileContent.replaceAll( "USER_NAME_1", user_name_1 );
+                fileContent = fileContent.replaceAll( "USER_NAME_2", user_name_2 );
+
+                fileContent = fileContent.replaceAll( "ORG_NAME_1", org_name_1 );
+                fileContent = fileContent.replaceAll( "ORG_NAME_2", org_name_2 );
+
+                FileOutputStream os = new FileOutputStream(
+                        tempDir.getAbsolutePath() + File.separator + fileName );
+
+                IOUtils.write( fileContent, os );
+                os.close();
+            }
+        }
+
+        // import data from temp directory
+
+        ImportAdmins importAdmins = new ImportAdmins();
+        importAdmins.startTool( new String[] {
+            "-host", "localhost:" + ServiceITSuite.cassandraResource.getRpcPort(),
+            "-inputDir", tempDir.getAbsolutePath()
+        }, false );
+
+        // verify that users and orgs were created correctly
+
+        OrganizationInfo orgInfo1 = setup.getMgmtSvc().getOrganizationByUuid( org_uuid_1 );
+        assertNotNull( orgInfo1 );
+
+        OrganizationInfo orgInfo2 = setup.getMgmtSvc().getOrganizationByUuid( org_uuid_2 );
+        assertNotNull( orgInfo2 );
+
+        BiMap<UUID, String> user1_orgs = setup.getMgmtSvc().getOrganizationsForAdminUser( user_uuid_1 );
+        assertEquals("user1 has two orgs", 2, user1_orgs.size() );
+
+        BiMap<UUID, String> user2_orgs = setup.getMgmtSvc().getOrganizationsForAdminUser( user_uuid_2 );
+        assertEquals("user2 has one orgs", 1, user2_orgs.size() );
+
+        List<UserInfo> org1_users = setup.getMgmtSvc().getAdminUsersForOrganization( org_uuid_1 );
+        assertEquals("org1 has one user", 1, org1_users.size() );
+
+        List<UserInfo> org2_users = setup.getMgmtSvc().getAdminUsersForOrganization( org_uuid_2 );
+        assertEquals("org2 has two users", 2, org2_users.size() );
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/test/resources/admin-user-metadata.usergrid-management.1433331614293.json
----------------------------------------------------------------------
diff --git a/stack/tools/src/test/resources/admin-user-metadata.usergrid-management.1433331614293.json b/stack/tools/src/test/resources/admin-user-metadata.usergrid-management.1433331614293.json
new file mode 100644
index 0000000..320f8ed
--- /dev/null
+++ b/stack/tools/src/test/resources/admin-user-metadata.usergrid-management.1433331614293.json
@@ -0,0 +1,85 @@
+{
+  "USER_UUID_1" : {
+    "activities" : [ ],
+    "devices" : [ ],
+    "feed" : [ "4c6275ba-09e5-11e5-bccc-97be717704cf" ],
+    "groups" : [ "4c5444ea-09e5-11e5-908d-61d76b477be4", "4c88c26a-09e5-11e5-8a66-594dd93a503d" ],
+    "roles" : [ ],
+    "connections" : { },
+    "organizations" : [ {
+      "uuid" : "ORG_UUID_1",
+      "name" : "ORG_NAME_1"
+    }, {
+      "uuid" : "ORG_UUID_2",
+      "name" : "ORG_NAME_2"
+    } ],
+    "dictionaries" : {
+      "credentials" : {
+        "mongo_pwd" : {
+          "recoverable" : true,
+          "encrypted" : false,
+          "secret" : "e045e38bbe5bf23334407ca9419ac94c",
+          "hashType" : null,
+          "created" : 1433331613575,
+          "cryptoChain" : [ "plaintext" ]
+        },
+        "password" : {
+          "recoverable" : false,
+          "encrypted" : true,
+          "secret" : "JDJhJDA5JEFpeC5IbHlpclo4ODFFVVNVTmN3Q3VEeGJ5emMyQlBwREN5WGZ6aHkydkVLdThJQlFzZExL",
+          "hashType" : null,
+          "created" : 1433331613505,
+          "cryptoChain" : [ "bcrypt" ]
+        },
+        "secret" : {
+          "recoverable" : true,
+          "encrypted" : false,
+          "secret" : "YWQ6bpC6YOMVf0s0dIQZ1CUdXIxDTY0",
+          "hashType" : null,
+          "created" : 1433331613575,
+          "cryptoChain" : [ "plaintext" ]
+        }
+      }
+    }
+  },
+  "USER_UUID_2" : {
+    "activities" : [ ],
+    "devices" : [ ],
+    "feed" : [ "4c8fee64-09e5-11e5-b3c6-57bd4e12c0b1" ],
+    "groups" : [ "4c88c26a-09e5-11e5-8a66-594dd93a503d" ],
+    "roles" : [ ],
+    "connections" : { },
+    "organizations" : [ {
+      "uuid" : "ORG_UUID_2",
+      "name" : "ORG_NAME_2"
+    } ],
+    "dictionaries" : {
+      "credentials" : {
+        "mongo_pwd" : {
+          "recoverable" : true,
+          "encrypted" : false,
+          "secret" : "e7b4fc7db5b97088997e44eced015d42",
+          "hashType" : null,
+          "created" : 1433331614067,
+          "cryptoChain" : [ "plaintext" ]
+        },
+        "password" : {
+          "recoverable" : false,
+          "encrypted" : true,
+          "secret" : "JDJhJDA5JER0RTdNSldMRjkxSUlJVm5hZWJMTy5DelFLemwvd2tXdUttaHViZWdyRjRURVdxYk5TUGJt",
+          "hashType" : null,
+          "created" : 1433331614018,
+          "cryptoChain" : [ "bcrypt" ]
+        },
+        "secret" : {
+          "recoverable" : true,
+          "encrypted" : false,
+          "secret" : "YWQ6Rx9A-m5U-TihpkPVS4PmyQO4qig",
+          "hashType" : null,
+          "created" : 1433331614067,
+          "cryptoChain" : [ "plaintext" ]
+        }
+      }
+    }
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/c5187d22/stack/tools/src/test/resources/admin-users.usergrid-management.1433331614293.json
----------------------------------------------------------------------
diff --git a/stack/tools/src/test/resources/admin-users.usergrid-management.1433331614293.json b/stack/tools/src/test/resources/admin-users.usergrid-management.1433331614293.json
new file mode 100644
index 0000000..5f192bf
--- /dev/null
+++ b/stack/tools/src/test/resources/admin-users.usergrid-management.1433331614293.json
@@ -0,0 +1,23 @@
+[ {
+  "uuid" : "USER_UUID_1",
+  "type" : "user",
+  "name" : "USER_NAME_1",
+  "created" : 1433331613479,
+  "modified" : 1433331613479,
+  "username" : "USER_NAME_1",
+  "email" : "USER_NAME_1@example.com",
+  "activated" : true,
+  "confirmed" : true,
+  "disabled" : false
+}, {
+  "uuid" : "USER_UUID_2",
+  "type" : "user",
+  "name" : "USER_NAME_2",
+  "created" : 1433331614002,
+  "modified" : 1433331614002,
+  "username" : "USER_NAME_2",
+  "email" : "USER_NAME_2@example.com",
+  "activated" : true,
+  "confirmed" : true,
+  "disabled" : false
+} ]
\ No newline at end of file