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 2015/06/01 23:48:26 UTC

[17/50] [abbrv] incubator-usergrid git commit: Merge branch 'master' into two-dot-o

Merge branch 'master' into two-dot-o

Conflicts:
	stack/config/src/main/resources/usergrid-default.properties
	stack/core/src/main/java/org/apache/usergrid/metrics/MetricsFactory.java
	stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
	stack/pom.xml
	stack/rest/pom.xml
	stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
	stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
	stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
	stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/filters/OAuth2AccessTokenSecurityFilter.java
	stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
	stack/rest/src/test/java/org/apache/usergrid/rest/management/ManagementResourceIT.java
	stack/rest/src/test/java/org/apache/usergrid/rest/management/users/MUUserResourceIT.java
	stack/services/src/main/java/org/apache/usergrid/services/assets/data/S3BinaryStore.java


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

Branch: refs/heads/USERGRID-628
Commit: a78401642d0de2981c497a7c69f20447b4d1c79a
Parents: cb44722 49ae4ac
Author: Dave Johnson <dm...@apigee.com>
Authored: Wed May 27 15:34:11 2015 -0400
Committer: Dave Johnson <dm...@apigee.com>
Committed: Wed May 27 15:34:11 2015 -0400

----------------------------------------------------------------------
 README.md                                       |   2 +-
 docs/file-storage-configuration.md              |  39 ++
 docs/get_2.0_running_locally.md                 | 165 ++++++
 docs/index.md                                   |   3 +-
 .../main/resources/usergrid-default.properties  |  24 +-
 .../persistence/cassandra/CassandraService.java |  79 +--
 .../org/apache/usergrid/utils/JsonUtils.java    |   2 +-
 stack/pom.xml                                   |  26 +-
 .../rest/applications/ServiceResource.java      |   2 +-
 .../rest/management/ManagementResource.java     | 442 +++++++++++++--
 .../organizations/OrganizationsResource.java    |  34 +-
 .../rest/management/users/UserResource.java     |  42 ++
 .../rest/management/users/UsersResource.java    |  45 +-
 .../OAuth2AccessTokenSecurityFilter.java        |   6 +-
 .../applications/assets/AssetResourceIT.java    | 302 +++++++---
 .../rest/applications/utils/UserRepo.java       |  36 +-
 .../rest/management/ManagementResourceIT.java   | 553 +++++++++++++++++--
 .../rest/test/PropertiesResourceIT.java         |  23 +-
 .../test/resource2point0/AbstractRestIT.java    |   2 -
 .../rest/test/resource2point0/ClientSetup.java  |  16 +-
 .../src/test/resources/cat-larger-than-6mb.jpg  | Bin 0 -> 9799257 bytes
 stack/services/pom.xml                          |  11 +
 .../usergrid/management/ManagementService.java  |   5 +-
 .../cassandra/ManagementServiceImpl.java        |   7 +
 .../apache/usergrid/security/shiro/Realm.java   |  10 +-
 .../usergrid/security/tokens/TokenService.java  |   3 +
 .../tokens/cassandra/TokenServiceImpl.java      |  44 +-
 .../assets/data/AwsSdkS3BinaryStore.java        | 230 ++++++++
 .../services/assets/data/S3BinaryStore.java     | 255 ++++++---
 .../security/tokens/TokenServiceIT.java         |  42 ++
 ugc/README.md                                   |   2 +-
 31 files changed, 2029 insertions(+), 423 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/README.md
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/config/src/main/resources/usergrid-default.properties
----------------------------------------------------------------------
diff --cc stack/config/src/main/resources/usergrid-default.properties
index 53b6445,0a4f218..e5e269e
--- a/stack/config/src/main/resources/usergrid-default.properties
+++ b/stack/config/src/main/resources/usergrid-default.properties
@@@ -78,8 -34,16 +78,12 @@@ cassandra.url=localhost:916
  # Name of Cassandra cluster
  cassandra.cluster=Test Cluster
  
+ # Keyspace names to be used (see also the locks keyspace below)
+ cassandra.system.keyspace=Usergrid
+ cassandra.application.keyspace=Usergrid_Applications
+ 
  cassandra.keyspace.strategy=org.apache.cassandra.locator.SimpleStrategy
  #cassandra.keyspace.strategy=org.apache.cassandra.locator.NetworkTopologyStrategy
 -
  #cassandra.keyspace.strategy.options.replication_factor=1
  #cassandra.keyspace.strategy.options.us-east=1
  
@@@ -88,37 -52,21 +92,37 @@@ cassandra.keyspace.replication=replicat
  cassandra.username=
  cassandra.password=
  
- #Read consistency level for the cassandra cluster
+ # Read consistency level for the cassandra cluster
  cassandra.readcl=QUORUM
  
- #Write consistency level for the cassandra cluster
+ # Write consistency level for the cassandra cluster
  cassandra.writecl=QUORUM
  
- #The maximum number of pending mutations allowed in ram before it is flushed to cassandra
+ # The maximum number of pending mutations allowed in ram before it is flushed to cassandra
  cassandra.mutation.flushsize=2000
  
 -# Keyspace to use for locking - Used by Hector lock manager:
 -# Note that if this is deployed in a production cluster, the RF on the keyspace MUST
 -# be updated to use an odd number for it's replication Factor. Even numbers for RF can
 -# potentially case the locks to fail, via "split brain" when read at QUORUM on lock verification
 +# Keyspace to use for locking
 +# Note that if this is deployed in a production cluster, the RF on the keyspace
 +# MUST be updated to use an odd number for it's replication Factor. Even numbers
 +# for RF can potentially case the locks to fail, via "split brain" when read at
 +# QUORUM on lock verification
  cassandra.lock.keyspace=Locks
  
 +# locking read & write policies
 +cassandra.lock.readcl=LOCAL_QUORUM
 +cassandra.lock.writecl=LOCAL_QUORUM
 +
 +# Timeout in ms before hector considers a thrift socket dead
 +cassandra.thriftSocketTimeout=0
 +# If hector should use host TCP keep alive settings
 +cassandra.useSocketKeepalive=false
 +
 +
 +
 +###############################################################################
 +#
 +# General properties
 +
  # false to disable test features
  usergrid.test=false
  
@@@ -132,31 -79,14 +136,32 @@@ usergrid.version.properties=1.0.
  # build number for display
  usergrid.version.build=${version}
  
 -usergird.service.packages=com.usergrid.services;org.apache.usergrid.services;baas.io
 +usergird.service.packages=org.apache.usergrid.services
  
 -#Batch submit counters ever 1000 updates
 +# Batch submit counters ever 1000 updates
  usergrid.counter.batch.size=1000
  
 -#Submit batcher every 30 seconds
 +# Submit batcher every 30 seconds
  usergrid.counter.batch.interval=30
  
 +AWS_ACCESS_KEY_ID=
 +AWS_SECRET_KEY=
 +usergrid.binary.bucketname=usergrid-test
- 
 +usergrid.test.sample_data_url=
++usergrid.binary.max-size-mb=50
++usergrid.binary.upload-workers=40
 +
 +# Disable Mongo API Server
 +usergrid.mongo.disable=true
 +
 +# Disable WebSocket Server
 +usergrid.websocket.disable=true
 +
 +
 +###############################################################################
 +#
 +# Authentication properties
 +
  #usergrid.auth.token_secret_salt=super secret token value
  #usergrid.auth.token_expires_from_last_use=false
  #usergrid.auth.token_refresh_reuses_id=false

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
----------------------------------------------------------------------
diff --cc stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
index 96d3fd9,43bfd2d..fb71b69
--- a/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
+++ b/stack/core/src/main/java/org/apache/usergrid/persistence/cassandra/CassandraService.java
@@@ -17,69 -17,69 +17,35 @@@
  package org.apache.usergrid.persistence.cassandra;
  
  
--import java.nio.ByteBuffer;
--import java.util.ArrayList;
--import java.util.Collection;
--import java.util.HashMap;
--import java.util.LinkedHashMap;
--import java.util.LinkedHashSet;
--import java.util.List;
--import java.util.Map;
--import java.util.Properties;
--import java.util.Set;
--import java.util.UUID;
 -import java.util.concurrent.Executors;
 -import java.util.concurrent.ScheduledExecutorService;
 -import java.util.concurrent.TimeUnit;
--
--import org.slf4j.Logger;
--import org.slf4j.LoggerFactory;
--import org.apache.usergrid.locking.LockManager;
--import org.apache.usergrid.persistence.IndexBucketLocator;
--import org.apache.usergrid.persistence.IndexBucketLocator.IndexType;
--import org.apache.usergrid.persistence.cassandra.index.IndexBucketScanner;
--import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
- import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
--import org.apache.usergrid.persistence.hector.CountingMutator;
- import org.apache.usergrid.utils.MapUtils;
--
 +import com.google.inject.Injector;
- 
  import me.prettyprint.cassandra.connection.HConnectionManager;
  import me.prettyprint.cassandra.model.ConfigurableConsistencyLevel;
--import me.prettyprint.cassandra.serializers.ByteBufferSerializer;
--import me.prettyprint.cassandra.serializers.BytesArraySerializer;
--import me.prettyprint.cassandra.serializers.DynamicCompositeSerializer;
--import me.prettyprint.cassandra.serializers.LongSerializer;
--import me.prettyprint.cassandra.serializers.StringSerializer;
--import me.prettyprint.cassandra.serializers.UUIDSerializer;
++import me.prettyprint.cassandra.serializers.*;
  import me.prettyprint.cassandra.service.CassandraHostConfigurator;
  import me.prettyprint.cassandra.service.ThriftKsDef;
--import me.prettyprint.hector.api.Cluster;
--import me.prettyprint.hector.api.ConsistencyLevelPolicy;
--import me.prettyprint.hector.api.HConsistencyLevel;
--import me.prettyprint.hector.api.Keyspace;
--import me.prettyprint.hector.api.Serializer;
--import me.prettyprint.hector.api.beans.ColumnSlice;
--import me.prettyprint.hector.api.beans.DynamicComposite;
--import me.prettyprint.hector.api.beans.HColumn;
--import me.prettyprint.hector.api.beans.OrderedRows;
--import me.prettyprint.hector.api.beans.Row;
--import me.prettyprint.hector.api.beans.Rows;
++import me.prettyprint.hector.api.*;
++import me.prettyprint.hector.api.beans.*;
  import me.prettyprint.hector.api.ddl.ColumnFamilyDefinition;
  import me.prettyprint.hector.api.ddl.KeyspaceDefinition;
  import me.prettyprint.hector.api.factory.HFactory;
  import me.prettyprint.hector.api.mutation.Mutator;
--import me.prettyprint.hector.api.query.ColumnQuery;
 -import me.prettyprint.hector.api.query.CountQuery;
--import me.prettyprint.hector.api.query.MultigetSliceQuery;
--import me.prettyprint.hector.api.query.QueryResult;
--import me.prettyprint.hector.api.query.RangeSlicesQuery;
--import me.prettyprint.hector.api.query.SliceQuery;
++import me.prettyprint.hector.api.query.*;
++import org.apache.usergrid.locking.LockManager;
++import org.apache.usergrid.persistence.IndexBucketLocator;
++import org.apache.usergrid.persistence.IndexBucketLocator.IndexType;
++import org.apache.usergrid.persistence.cassandra.index.IndexBucketScanner;
++import org.apache.usergrid.persistence.cassandra.index.IndexScanner;
++import org.apache.usergrid.persistence.core.astyanax.CassandraFig;
++import org.apache.usergrid.persistence.hector.CountingMutator;
++import org.apache.usergrid.utils.MapUtils;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
  
--import static me.prettyprint.cassandra.service.FailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE;
--import static me.prettyprint.hector.api.factory.HFactory.createColumn;
--import static me.prettyprint.hector.api.factory.HFactory.createMultigetSliceQuery;
++import java.nio.ByteBuffer;
++import java.util.*;
  
--import static me.prettyprint.hector.api.factory.HFactory.createRangeSlicesQuery;
--import static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;
--import static me.prettyprint.hector.api.factory.HFactory.createVirtualKeyspace;
++import static me.prettyprint.cassandra.service.FailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE;
++import static me.prettyprint.hector.api.factory.HFactory.*;
  import static org.apache.commons.collections.MapUtils.getIntValue;
  import static org.apache.commons.collections.MapUtils.getString;
  import static org.apache.usergrid.persistence.cassandra.ApplicationCF.ENTITY_ID_SETS;
@@@ -93,11 -94,8 +59,13 @@@ import static org.apache.usergrid.utils
  
  public class CassandraService {
  
 +    //make the below two not static
 +   // public static String SYSTEM_KEYSPACE = "Usergrid";
 +
 +    public static String applicationKeyspace;
 +
+     public static final boolean USE_VIRTUAL_KEYSPACES = true;
+ 
      public static final String APPLICATIONS_CF = "Applications";
      public static final String PROPERTIES_CF = "Properties";
      public static final String TOKENS_CF = "Tokens";

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/core/src/main/java/org/apache/usergrid/utils/JsonUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/pom.xml
----------------------------------------------------------------------
diff --cc stack/pom.xml
index c458acb,5c3d4fe..cc61a7c
--- a/stack/pom.xml
+++ b/stack/pom.xml
@@@ -177,52 -154,21 +177,35 @@@
        <id>tonuquq</id>
        <name>Alex Karasulu</name>
      </developer>
 +    <developer>
 +      <id>snoopdave</id>
 +      <name>Dave Johnson</name>
 +    </developer>
    </developers>
  
- 
-   <distributionManagement>
-     <!-- Versioned (non-snapshot) releases are published to this repository -->
-     <repository>
-       <id>usergrid.releases</id>
-       <name>Usergrid Releases</name>
-       <url>${release.repository.url}</url>
-     </repository>
- 
-     <!-- Snapshots (not-releases) are published to this repository -->
-     <snapshotRepository>
-       <id>usergrid.snapshots</id>
-       <name>Usergrid Snapshots</name>
-       <url>${snapshot.repository.url}</url>
-     </snapshotRepository>
-   </distributionManagement>
- 
    <modules>
 -    <module>java-sdk-old</module>
 +    <module>build-tools</module>
 +    <module>test-utils</module>
      <module>config</module>
 +    <module>corepersistence</module>
      <module>core</module>
      <module>services</module>
 +    <module>rest</module>
 +    <!--
      <module>tools</module>
 -    <module>mongo-emulator</module>
      <module>websocket</module>
 -    <module>rest</module>
 +    -->
 +    <!--
 +    Re-enable when we have a fix for the AppleJavaExtensions jar issue
 +    https://issues.apache.org/jira/browse/USERGRID-224
      <module>launcher</module>
 -    <module>test-utils</module>
 -    <!--<module>query-validator</module>-->
 -    <module>build-tools</module>
 +    -->
 +    <module>mongo-emulator</module>
 +    <!--
 +    Re-enable when query-validator updated to work with Core Persistence.
 +    https://issues.apache.org/jira/browse/USERGRID-221
 +    <module>query-validator</module>
 +    -->
    </modules>
  
    <dependencyManagement>
@@@ -295,8 -241,15 +278,15 @@@
            </exclusion>
          </exclusions>
        </dependency>
 -      
 +
        <dependency>
+         <groupId>com.amazonaws</groupId>
+         <artifactId>aws-java-sdk-s3</artifactId>
+         <version>1.9.31</version>
+       </dependency>
+ 
+ 
+       <dependency>
          <groupId>org.apache.activemq</groupId>
          <artifactId>activemq-spring</artifactId>
          <version>5.5.0</version>

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
index a5ff3e3,46d6d6b..acbd84f
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/ManagementResource.java
@@@ -17,39 -17,39 +17,36 @@@
  package org.apache.usergrid.rest.management;
  
  
- import java.net.URLEncoder;
- import java.util.Map;
- 
- import javax.ws.rs.Consumes;
- import javax.ws.rs.DefaultValue;
- import javax.ws.rs.FormParam;
- import javax.ws.rs.GET;
- import javax.ws.rs.HeaderParam;
- import javax.ws.rs.POST;
- import javax.ws.rs.Path;
- import javax.ws.rs.Produces;
- import javax.ws.rs.QueryParam;
- import javax.ws.rs.core.Context;
- import javax.ws.rs.core.MediaType;
- import javax.ws.rs.core.Response;
- import javax.ws.rs.core.UriInfo;
- 
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.context.annotation.Scope;
- import org.springframework.stereotype.Component;
- 
+ import com.codahale.metrics.Counter;
+ import com.codahale.metrics.Timer;
++import com.google.inject.Injector;
+ import com.sun.jersey.api.client.Client;
+ import com.sun.jersey.api.client.config.ClientConfig;
+ import com.sun.jersey.api.client.config.DefaultClientConfig;
+ import com.sun.jersey.api.json.JSONConfiguration;
+ import com.sun.jersey.api.view.Viewable;
+ import com.sun.jersey.client.apache.ApacheHttpClient;
+ import com.sun.jersey.client.apache.ApacheHttpClientHandler;
  import org.apache.amber.oauth2.common.error.OAuthError;
  import org.apache.amber.oauth2.common.exception.OAuthProblemException;
  import org.apache.amber.oauth2.common.message.OAuthResponse;
  import org.apache.amber.oauth2.common.message.types.GrantType;
+ import org.apache.commons.httpclient.HttpClient;
 -import org.apache.commons.httpclient.HttpConnectionManager;
+ import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 -import org.apache.commons.httpclient.params.HttpClientParams;
+ import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
 -import org.apache.commons.httpclient.params.HttpMethodParams;
+ import org.apache.commons.lang.RandomStringUtils;
  import org.apache.commons.lang.StringUtils;
 -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  import org.apache.shiro.codec.Base64;
- 
+ import org.apache.usergrid.exception.NotImplementedException;
+ import org.apache.usergrid.management.ApplicationCreator;
+ import org.apache.usergrid.management.OrganizationInfo;
+ import org.apache.usergrid.management.OrganizationOwnerInfo;
  import org.apache.usergrid.management.UserInfo;
  import org.apache.usergrid.management.exceptions.DisabledAdminUserException;
  import org.apache.usergrid.management.exceptions.UnactivatedAdminUserException;
  import org.apache.usergrid.management.exceptions.UnconfirmedAdminUserException;
 -import org.apache.usergrid.metrics.MetricsFactory;
++import org.apache.usergrid.persistence.core.metrics.MetricsFactory;
+ import org.apache.usergrid.persistence.exceptions.EntityNotFoundException;
  import org.apache.usergrid.rest.AbstractContextResource;
  import org.apache.usergrid.rest.exceptions.RedirectionException;
  import org.apache.usergrid.rest.management.organizations.OrganizationsResource;
@@@ -90,17 -104,36 +101,48 @@@ public class ManagementResource extend
       *
       * /management/users/<user-name>/login
       * /management/users/<user-name>/password
--     * 
++     *
       */
  
-     private static final Logger logger = LoggerFactory.getLogger( ManagementResource.class );
+     @Autowired
+     private ApplicationCreator applicationCreator;
+ 
+     @Autowired
 -    MetricsFactory metricsFactory;
++    Injector injector;
++
+ 
+     private static Client jerseyClient = null;
+ 
+ 
+     // names for metrics to be collected
+     private static final String SSO_TOKENS_REJECTED = "sso_tokens_rejected";
+     private static final String SSO_TOKENS_VALIDATED = "sso_tokens_validated";
+     private static final String SSO_CREATED_LOCAL_ADMINS = "sso_created_local_admins";
+     private static final String SSO_PROCESSING_TIME = "sso_processing_time";
+ 
+     // usergrid configuration property names needed
+     public static final String USERGRID_SYSADMIN_LOGIN_NAME = "usergrid.sysadmin.login.name";
+     public static final String USERGRID_CENTRAL_URL =         "usergrid.central.url";
+     public static final String CENTRAL_CONNECTION_POOL_SIZE = "usergrid.central.connection.pool.size";
+     public static final String CENTRAL_CONNECTION_TIMEOUT =   "usergrid.central.connection.timeout";
+     public static final String CENTRAL_READ_TIMEOUT =         "usergrid.central.read.timeout";
+ 
++    MetricsFactory metricsFactory = null;
 +
 +
      public ManagementResource() {
          logger.info( "ManagementResource initialized" );
      }
  
  
++    MetricsFactory getMetricsFactory() {
++        if ( metricsFactory == null ) {
++            metricsFactory = injector.getInstance( MetricsFactory.class );
++        }
++        return metricsFactory;
++    }
++
++
      private static String wrapWithCallback( AccessInfo accessInfo, String callback ) {
          return wrapWithCallback( mapToJsonString( accessInfo ), callback );
      }
@@@ -446,6 -484,308 +498,308 @@@
      }
  
  
+     /**
+      * <p>
+      * Allows call to validateExternalToken() (see below) with a POST of a JSON object.
+      * </p>
+      *
+      * @param ui             Information about calling URI.
+      * @param json           JSON object with fields: ext_access_token, ttl
+      * @param callback       For JSONP support.
+      * @return               Returns JSON object with access_token field.
+      * @throws Exception     Returns 401 if access token cannot be validated
+      */
+     @POST
+     @Path( "/externaltoken" )
+     public Response validateExternalToken(
+             @Context UriInfo ui,
+             Map<String, Object> json,
+             @QueryParam( "callback" ) @DefaultValue( "" ) String callback )  throws Exception {
+ 
+         if ( StringUtils.isEmpty( properties.getProperty( USERGRID_CENTRAL_URL ))) {
+             throw new NotImplementedException( "External Token Validation Service is not configured" );
+         }
+ 
+         Object extAccessTokenObj = json.get( "ext_access_token" );
+         if ( extAccessTokenObj == null ) {
+             throw new IllegalArgumentException("ext_access_token must be specified");
+         }
+         String extAccessToken = json.get("ext_access_token").toString();
+ 
+         Object ttlObj = json.get( "ttl" );
+         if ( ttlObj == null ) {
+             throw new IllegalArgumentException("ttl must be specified");
+         }
+         long ttl;
+         try {
+             ttl = Long.parseLong(ttlObj.toString());
+         } catch ( NumberFormatException e ) {
+             throw new IllegalArgumentException("ttl must be specified as a long");
+         }
+ 
+         return validateExternalToken( ui, extAccessToken, ttl, callback );
+     }
+ 
+ 
+     /**
+      * <p>
+      * Validates access token from other or "external" Usergrid system.
+      * Calls other system's /management/me endpoint to get the User
+      * associated with the access token. If user does not exist locally,
+      * then user and organizations will be created. If no user is returned
+      * from the other cluster, then this endpoint will return 401.
+      * </p>
+      *
+      * <p> Part of Usergrid Central SSO feature.
+      * See <a href="https://issues.apache.org/jira/browse/USERGRID-567">USERGRID-567</a>
+      * for details about Usergrid Central SSO.
+      * </p>
+      *
+      * @param ui             Information about calling URI.
+      * @param extAccessToken Access token from external Usergrid system.
+      * @param ttl            Time to live for token.
+      * @param callback       For JSONP support.
+      * @return               Returns JSON object with access_token field.
+      * @throws Exception     Returns 401 if access token cannot be validated
+      */
+     @GET
+     @Path( "/externaltoken" )
+     public Response validateExternalToken(
+                                 @Context UriInfo ui,
+                                 @QueryParam( "ext_access_token" ) String extAccessToken,
+                                 @QueryParam( "ttl" ) @DefaultValue("-1") long ttl,
+                                 @QueryParam( "callback" ) @DefaultValue( "" ) String callback )
+             throws Exception {
+ 
+ 
+         if ( StringUtils.isEmpty( properties.getProperty( USERGRID_CENTRAL_URL ))) {
+             throw new NotImplementedException( "External Token Validation Service is not configured" );
+         }
+ 
+         if ( extAccessToken == null ) {
+             throw new IllegalArgumentException("ext_access_token must be specified");
+         }
+ 
+         if ( ttl == -1 ) {
+             throw new IllegalArgumentException("ttl must be specified");
+         }
+         AccessInfo accessInfo = null;
+ 
 -        Timer processingTimer = metricsFactory.getTimer(
 -                ManagementResource.class, SSO_PROCESSING_TIME );
++        Timer processingTimer = getMetricsFactory().getTimer(
++            ManagementResource.class, SSO_PROCESSING_TIME );
+ 
+         Timer.Context timerContext = processingTimer.time();
+ 
+         try {
+             // look up user via UG Central's /management/me endpoint.
+ 
+             JsonNode accessInfoNode = getMeFromUgCentral( extAccessToken );
+ 
+             JsonNode userNode = accessInfoNode.get( "user" );
+             String username = userNode.get( "username" ).getTextValue();
+ 
+             // if user does not exist locally then we need to fix that
+ 
+             UserInfo userInfo = management.getAdminUserByUsername( username );
+             UUID userId = userInfo == null ? null : userInfo.getUuid();
+ 
+             if ( userId == null ) {
+ 
+                 // create local user and and organizations they have on the central Usergrid instance
+                 logger.info("User {} does not exist locally, creating", username );
+ 
+                 String name  = userNode.get( "name" ).getTextValue();
+                 String email = userNode.get( "email" ).getTextValue();
+                 String dummyPassword = RandomStringUtils.randomAlphanumeric( 40 );
+ 
+                 JsonNode orgsNode = userNode.get( "organizations" );
+                 Iterator<String> fieldNames = orgsNode.getFieldNames();
+ 
+                 if ( !fieldNames.hasNext() ) {
+                     // no organizations for user exist in response from central Usergrid SSO
+                     // so create user's personal organization and use username as organization name
+                     fieldNames = Collections.singletonList( username ).iterator();
+                 }
+ 
+                 // create user and any organizations that user is supposed to have
+ 
+                 while ( fieldNames.hasNext() ) {
+ 
+                     String orgName = fieldNames.next();
+ 
+                     if ( userId == null ) {
+ 
+                         // haven't created user yet so do that now
+                         OrganizationOwnerInfo ownerOrgInfo = management.createOwnerAndOrganization(
+                                 orgName, username, name, email, dummyPassword, true, false );
+ 
+                         applicationCreator.createSampleFor( ownerOrgInfo.getOrganization() );
+ 
+                         userId = ownerOrgInfo.getOwner().getUuid();
+                         userInfo = ownerOrgInfo.getOwner();
+ 
 -                        Counter createdAdminsCounter = metricsFactory.getCounter(
 -                                ManagementResource.class, SSO_CREATED_LOCAL_ADMINS );
++                        Counter createdAdminsCounter = getMetricsFactory().getCounter(
++                            ManagementResource.class, SSO_CREATED_LOCAL_ADMINS );
+                         createdAdminsCounter.inc();
+ 
+                         logger.info( "Created user {} and org {}", username, orgName );
+ 
+                     } else {
+ 
+                         // already created user, so just create an org
+                         final OrganizationInfo organization = management.createOrganization( orgName, userInfo, true );
+ 
+                         applicationCreator.createSampleFor( organization );
+ 
+                         logger.info( "Created user {}'s other org {}", username, orgName );
+                     }
+                 }
+ 
+             }
+ 
+             // store the external access_token as if it were one of our own
+             management.importTokenForAdminUser( userId, extAccessToken, ttl );
+ 
+             // success! return JSON object with access_token field
+             accessInfo = new AccessInfo()
+                     .withExpiresIn( tokens.getMaxTokenAgeInSeconds( extAccessToken ) )
+                     .withAccessToken( extAccessToken );
+ 
+         } catch (Exception e) {
+             timerContext.stop();
+             logger.debug("Error validating external token", e);
+             throw e;
+         }
+ 
+         final Response response = Response.status( SC_OK ).type( jsonMediaType( callback ) ).entity( accessInfo ).build();
+ 
+         timerContext.stop();
+ 
+         return response;
+     }
+ 
+     /**
+      * Look up Admin User via UG Central's /management/me endpoint.
+      *
+      * @param extAccessToken Access token issued by UG Central of Admin User
+      * @return JsonNode representation of AccessInfo object for Admin User
+      * @throws EntityNotFoundException if access_token is not valid.
+      */
+     private JsonNode getMeFromUgCentral( String extAccessToken )  throws EntityNotFoundException {
+ 
+         // prepare to count tokens validated and rejected
+ 
 -        Counter tokensRejectedCounter = metricsFactory.getCounter(
 -                ManagementResource.class, SSO_TOKENS_REJECTED );
 -        Counter tokensValidatedCounter = metricsFactory.getCounter(
++        Counter tokensRejectedCounter = getMetricsFactory().getCounter(
++            ManagementResource.class, SSO_TOKENS_REJECTED );
++        Counter tokensValidatedCounter = getMetricsFactory().getCounter(
+                 ManagementResource.class, SSO_TOKENS_VALIDATED );
+ 
+         // create URL of central Usergrid's /management/me endpoint
+ 
+         String externalUrl = properties.getProperty( USERGRID_CENTRAL_URL ).trim();
+ 
+         // be lenient about trailing slash
+         externalUrl = !externalUrl.endsWith( "/" ) ? externalUrl + "/" : externalUrl;
+         String me = externalUrl + "management/me?access_token=" + extAccessToken;
+ 
+         // use our favorite HTTP client to GET /management/me
+ 
+         Client client = getJerseyClient();
+         final JsonNode accessInfoNode;
+         try {
+             accessInfoNode = client.resource( me )
+                     .type( MediaType.APPLICATION_JSON_TYPE)
+                     .get(JsonNode.class);
+ 
+             tokensValidatedCounter.inc();
+ 
+         } catch ( Exception e ) {
+             // user not found 404
+             tokensRejectedCounter.inc();
+             String msg = "Cannot find Admin User associated with " + extAccessToken;
+             throw new EntityNotFoundException( msg, e );
+         }
+ 
+         return accessInfoNode;
+     }
+ 
+ 
+     private Client getJerseyClient() {
+ 
+         if ( jerseyClient == null ) {
+ 
+             synchronized ( this ) {
+ 
+                 // create HTTPClient and with configured connection pool
+ 
+                 int poolSize = 100; // connections
+                 final String poolSizeStr = properties.getProperty( CENTRAL_CONNECTION_POOL_SIZE );
+                 if ( poolSizeStr != null ) {
+                     poolSize = Integer.parseInt( poolSizeStr );
+                 }
+ 
+                 MultiThreadedHttpConnectionManager cm = new MultiThreadedHttpConnectionManager();
+                 HttpConnectionManagerParams cmParams = cm.getParams();
+                 cmParams.setMaxTotalConnections( poolSize );
+                 HttpClient httpClient = new HttpClient( cm );
+ 
+                 // create Jersey Client using that HTTPClient and with configured timeouts
+ 
+                 int timeout = 20000; // ms
+                 final String timeoutStr = properties.getProperty( CENTRAL_CONNECTION_TIMEOUT );
+                 if ( timeoutStr != null ) {
+                     timeout = Integer.parseInt( timeoutStr );
+                 }
+ 
+                 int readTimeout = 20000; // ms
+                 final String readTimeoutStr = properties.getProperty( CENTRAL_READ_TIMEOUT );
+                 if ( readTimeoutStr != null ) {
+                     readTimeout = Integer.parseInt( readTimeoutStr );
+                 }
+ 
+                 ClientConfig clientConfig = new DefaultClientConfig();
+                 clientConfig.getFeatures().put( JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE );
+                 clientConfig.getProperties().put( ClientConfig.PROPERTY_CONNECT_TIMEOUT, timeout ); // ms
+                 clientConfig.getProperties().put( ClientConfig.PROPERTY_READ_TIMEOUT, readTimeout ); // ms
+ 
+                 ApacheHttpClientHandler handler = new ApacheHttpClientHandler( httpClient, clientConfig );
+                 jerseyClient = new ApacheHttpClient( handler );
+ 
+             }
+         }
+ 
+         return jerseyClient;
+     }
+ 
+ 
+     /**
+      * Check that authentication is allowed. If external token validation is enabled (Central Usergrid SSO)
+      * then only superusers should be allowed to login directly to this Usergrid instance.
+      */
+     private void ensureAuthenticationAllowed( String username, String grant_type ) {
+ 
+         if ( username == null || grant_type == null || !grant_type.equalsIgnoreCase( "password" )) {
+             return; // we only care about username/password auth
+         }
+ 
+         final boolean externalTokensEnabled =
+                 !StringUtils.isEmpty( properties.getProperty( USERGRID_CENTRAL_URL ) );
+ 
+         if ( externalTokensEnabled ) {
+ 
+             // when external tokens enabled then only superuser can obtain an access token
+ 
+             final String superuserName = properties.getProperty( USERGRID_SYSADMIN_LOGIN_NAME );
+             if ( !username.equalsIgnoreCase( superuserName )) {
+ 
+                 // this guy is not the superuser
+                 throw new IllegalArgumentException( "Admin Users must login via " +
+                         properties.getProperty( USERGRID_CENTRAL_URL ) );
+             }
+         }
+     }
+ 
+ 
      String errorMsg = "";
      String responseType;
      String clientId;

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
index e6f3de2,e4e9eda..6f3edc2
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/organizations/OrganizationsResource.java
@@@ -151,12 -147,20 +152,23 @@@ public class OrganizationsResource exte
      /** Create a new organization */
      private JSONWithPadding newOrganization( @Context UriInfo ui, String organizationName, String username, String name,
                                               String email, String password, Map<String, Object> userProperties,
-                                              Map<String, Object> properties, String callback ) throws Exception {
+                                              Map<String, Object> orgProperties, String callback ) throws Exception {
  
-         Preconditions.checkArgument( 
+         final boolean externalTokensEnabled =
+                 !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) );
+ 
+         if ( externalTokensEnabled ) {
+             throw new IllegalArgumentException( "Organization / Admin Users must be created via " +
+                     properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) );
+         }
+ 
+         Preconditions
+                 .checkArgument( StringUtils.isNotBlank( organizationName ), "The organization parameter was missing" );
+ 
 -        logger.info( "New organization: {}", organizationName );
++        Preconditions.checkArgument(
 +            StringUtils.isNotBlank( organizationName ), "The organization parameter was missing" );
 +
 +        logger.debug( "New organization: {}", organizationName );
  
          ApiResponse response = createApiResponse();
          response.setAction( "new organization" );
@@@ -181,18 -185,18 +193,18 @@@
  
      /*
       * @POST
--     * 
++     *
       * @Consumes(MediaType.MULTIPART_FORM_DATA) public JSONWithPadding
       * newOrganizationFromMultipart(@Context UriInfo ui,
--     * 
++     *
       * @FormDataParam("organization") String organization,
--     * 
++     *
       * @FormDataParam("username") String username,
--     * 
++     *
       * @FormDataParam("name") String name,
--     * 
++     *
       * @FormDataParam("email") String email,
--     * 
++     *
       * @FormDataParam("password") String password) throws Exception { return
       * newOrganizationFromForm(ui, organization, username, name, email,
       * password); }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
index 7c7dc72,3c755f8..7ea4eec
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UserResource.java
@@@ -234,8 -244,14 +244,16 @@@ public class UserResource extends Abstr
                                               @FormParam( "recaptcha_challenge_field" ) String challenge,
                                               @FormParam( "recaptcha_response_field" ) String uresponse ) {
  
 +        logger.debug("handlePasswordResetForm");
 +
+         final boolean externalTokensEnabled =
+                 !StringUtils.isEmpty( properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) );
+ 
+         if ( externalTokensEnabled ) {
+             throw new IllegalArgumentException( "Admin Users must reset passwords via " +
+                     properties.getProperty( ManagementResource.USERGRID_CENTRAL_URL ) );
+         }
+ 
          try {
              this.token = token;
  

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
index 2d5b7a9,d907632..7165d08
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/management/users/UsersResource.java
@@@ -17,39 -17,47 +17,36 @@@
  package org.apache.usergrid.rest.management.users;
  
  
 -import java.util.LinkedHashMap;
 -import java.util.Map;
 -import java.util.UUID;
 -
 -import javax.ws.rs.Consumes;
 -import javax.ws.rs.DefaultValue;
 -import javax.ws.rs.FormParam;
 -import javax.ws.rs.GET;
 -import javax.ws.rs.POST;
 -import javax.ws.rs.Path;
 -import javax.ws.rs.PathParam;
 -import javax.ws.rs.Produces;
 -import javax.ws.rs.QueryParam;
 -import javax.ws.rs.core.Context;
 -import javax.ws.rs.core.MediaType;
 -import javax.ws.rs.core.UriInfo;
 -
 +import com.sun.jersey.api.json.JSONWithPadding;
 +import com.sun.jersey.api.view.Viewable;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import java.util.UUID;
- import javax.ws.rs.Consumes;
- import javax.ws.rs.DefaultValue;
- import javax.ws.rs.FormParam;
- import javax.ws.rs.GET;
- import javax.ws.rs.POST;
- import javax.ws.rs.Path;
- import javax.ws.rs.PathParam;
- import javax.ws.rs.Produces;
- import javax.ws.rs.QueryParam;
- import javax.ws.rs.core.Context;
- import javax.ws.rs.core.MediaType;
- import javax.ws.rs.core.UriInfo;
 +import net.tanesha.recaptcha.ReCaptchaImpl;
 +import net.tanesha.recaptcha.ReCaptchaResponse;
- import static org.apache.commons.lang.StringUtils.isBlank;
+ import org.apache.commons.lang.StringUtils;
 -import org.apache.usergrid.management.exceptions.ManagementException;
 -import org.apache.usergrid.rest.RootResource;
 -import org.apache.usergrid.rest.management.ManagementResource;
 -import org.apache.usergrid.services.exceptions.ServiceResourceNotFoundException;
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -import org.springframework.stereotype.Component;
  import org.apache.usergrid.management.UserInfo;
 +import org.apache.usergrid.management.exceptions.ManagementException;
++
  import org.apache.usergrid.rest.AbstractContextResource;
  import org.apache.usergrid.rest.ApiResponse;
 +import org.apache.usergrid.rest.RootResource;
  import org.apache.usergrid.rest.exceptions.AuthErrorInfo;
  import org.apache.usergrid.rest.exceptions.RedirectionException;
- import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
++import org.apache.usergrid.rest.management.ManagementResource;
  import org.apache.usergrid.security.shiro.utils.SubjectUtils;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +import org.springframework.stereotype.Component;
  
 -import com.sun.jersey.api.json.JSONWithPadding;
 -import com.sun.jersey.api.view.Viewable;
 -
 -import net.tanesha.recaptcha.ReCaptchaImpl;
 -import net.tanesha.recaptcha.ReCaptchaResponse;
++import javax.ws.rs.*;
++import javax.ws.rs.core.Context;
++import javax.ws.rs.core.MediaType;
++import javax.ws.rs.core.UriInfo;
++import java.util.LinkedHashMap;
++import java.util.Map;
++import java.util.UUID;
+ 
+ import static org.apache.commons.lang.StringUtils.isBlank;
+ import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
+ 
  
  @Component( "org.apache.usergrid.rest.management.users.UsersResource" )
  @Produces( {

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/filters/OAuth2AccessTokenSecurityFilter.java
----------------------------------------------------------------------
diff --cc stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/filters/OAuth2AccessTokenSecurityFilter.java
index 36a91bf,e3a7d54..87b85ac
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/filters/OAuth2AccessTokenSecurityFilter.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/security/shiro/filters/OAuth2AccessTokenSecurityFilter.java
@@@ -107,12 -104,13 +107,16 @@@ public class OAuth2AccessTokenSecurityF
                  catch ( InvalidTokenException ite ) {
                      throw mappableSecurityException( INVALID_AUTH_ERROR );
                  }
+                 catch ( IndexOutOfBoundsException ioobe ) {
+                     // token is just some rubbish string
+                     throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
+                 }
                  catch ( Exception e ) {
 -                    // unexpected so we log it
 -                    LOG.error( "unable to verify oauth token", e );
 +                    if ( LOG.isDebugEnabled() ) {
 +                        LOG.debug( "Unable to verify OAuth token: " + accessToken, e );
 +                    } else {
 +                        LOG.warn( "Unable to verify OAuth token" );
 +                    }
                      throw mappableSecurityException( UNVERIFIED_OAUTH_ERROR );
                  }
  
@@@ -138,8 -136,7 +142,8 @@@
                          throw mappableSecurityException( BAD_ACCESS_TOKEN_ERROR );
                      }
  
-                     token = PrincipalCredentialsToken.getFromAdminUserInfoAndAccessToken( 
 -                    token = PrincipalCredentialsToken.getFromAdminUserInfoAndAccessToken( user, accessToken );
++                    token = PrincipalCredentialsToken.getFromAdminUserInfoAndAccessToken(
 +                            user, accessToken, emf.getManagementAppId() );
                  }
                  else if ( AuthPrincipalType.APPLICATION_USER.equals( principal.getType() ) ) {
  

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
----------------------------------------------------------------------
diff --cc stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
index dadc87d,c3cab63..6455748
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
@@@ -17,124 -17,116 +17,128 @@@
  package org.apache.usergrid.rest.applications.assets;
  
  
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Map;
- import java.util.UUID;
- import java.util.concurrent.TimeoutException;
- 
- import javax.ws.rs.core.MediaType;
- 
 +import com.fasterxml.jackson.databind.JsonNode;
++import com.sun.jersey.multipart.FormDataMultiPart;
++import org.apache.commons.io.IOUtils;
++import org.apache.usergrid.rest.applications.utils.UserRepo;
 +import org.apache.usergrid.rest.test.resource2point0.AbstractRestIT;
++import org.apache.usergrid.services.assets.data.AssetUtils;
 +import org.junit.Assert;
 +import org.junit.Before;
- import org.junit.Ignore;
 +import org.junit.Test;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +
- import org.apache.usergrid.rest.applications.utils.UserRepo;
- import org.apache.usergrid.services.assets.data.AssetUtils;
- 
- import org.apache.commons.io.IOUtils;
- 
- import com.sun.jersey.multipart.FormDataMultiPart;
++import javax.ws.rs.core.MediaType;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.UUID;
+ import java.util.concurrent.TimeoutException;
  
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
 -import javax.ws.rs.core.MediaType;
 -
 -import org.codehaus.jackson.JsonNode;
 -import org.junit.Assert;
 -import org.junit.Ignore;
 -import org.junit.Test;
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -import org.apache.usergrid.cassandra.Concurrent;
 -import org.apache.usergrid.rest.AbstractRestIT;
 -import org.apache.usergrid.rest.applications.utils.UserRepo;
 -import org.apache.usergrid.services.assets.data.AssetUtils;
 -
 -import org.apache.commons.io.IOUtils;
 -
 -import com.sun.jersey.multipart.FormDataMultiPart;
 -
 -import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_ADMIN_USERS_REQUIRE_CONFIRMATION;
++import static org.apache.usergrid.utils.JsonUtils.mapToFormattedJsonString;
  import static org.apache.usergrid.utils.MapUtils.hashMap;
- 
+ import static org.junit.Assert.*;
  
  
 -@Concurrent()
  public class AssetResourceIT extends AbstractRestIT {
  
 +    private String access_token;
      private Logger LOG = LoggerFactory.getLogger( AssetResourceIT.class );
 +    UserRepo userRepo;
 +
 +    @Before
 +    public void setup(){
 +        userRepo = new UserRepo(this.clientSetup);
 +        access_token = this.getAdminToken().getAccessToken();
 +    }
  
  
      /** @Deprecated Tests legacy API */
      @Test
      public void verifyBinaryCrud() throws Exception {
 -        UserRepo.INSTANCE.load( resource(), access_token );
  
 -        UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
++        userRepo.load();
++
++        this.refreshIndex();
++
 +        UUID userId = userRepo.getByUserName( "user1" );
          Map<String, String> payload =
                  hashMap( "path", "my/clean/path" ).map( "owner", userId.toString() ).map( "someprop", "somevalue" );
  
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
          JsonNode node =
-                 mapper.readTree( resource().path( "/test-organization/test-app/assets" ).queryParam( "access_token", access_token )
 -                resource().path( "/test-organization/test-app/assets" ).queryParam( "access_token", access_token )
--                        .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
-                         .post( String.class, payload ));
 -                        .post( JsonNode.class, payload );
++                mapper.readTree( resource().path( orgAppPath + "/assets" ).queryParam( "access_token", access_token )
++                    .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
++                    .post( String.class, payload ) );
          JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        UUID id = UUID.fromString( idNode.getTextValue() );
 -        assertNotNull( idNode.getTextValue() );
 -        logNode( node );
 +        UUID id = UUID.fromString( idNode.textValue() );
-         assertNotNull(idNode.textValue());
++        assertNotNull( idNode.textValue() );
  
          byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
--        resource().path( "/test-organization/test-app/assets/" + id.toString() + "/data" )
++        resource().path( orgAppPath + "/assets/" + id.toString() + "/data" )
                  .queryParam( "access_token", access_token ).type( MediaType.APPLICATION_OCTET_STREAM_TYPE ).put( data );
  
--        InputStream is = resource().path( "/test-organization/test-app/assets/" + id.toString() + "/data" )
++        InputStream is = resource().path( orgAppPath + "/assets/" + id.toString() + "/data" )
                  .queryParam( "access_token", access_token ).get( InputStream.class );
  
          byte[] foundData = IOUtils.toByteArray( is );
          assertEquals( 7979, foundData.length );
  
 -        node = resource().path( "/test-organization/test-app/assets/my/clean/path" )
 -                .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
 -                .get( JsonNode.class );
 +        refreshIndex();
 +
-         node = mapper.readTree( resource().path( "/test-organization/test-app/assets/my/clean/path" )
-                 .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
-                 .get( String.class ));
++        node = mapper.readTree( resource().path( orgAppPath + "/assets/my/clean/path" )
++            .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
++            .get( String.class ) );
  
          idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        assertEquals( id.toString(), idNode.getTextValue() );
 +        assertEquals( id.toString(), idNode.textValue() );
      }
  
  
      @Test
      public void octetStreamOnDynamicEntity() throws Exception {
 -        UserRepo.INSTANCE.load( resource(), access_token );
 +
++        this.refreshIndex();
+ 
          Map<String, String> payload = hashMap( "name", "assetname" );
  
-         JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
 -        JsonNode node = resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
--                .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
-                 .post( String.class, payload ));
 -                .post( JsonNode.class, payload );
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
++        JsonNode node = mapper.readTree( resource().path( orgAppPath + "/foos" ).queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
++            .post( String.class, payload ) );
  
          JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        String uuid = idNode.getTextValue();
 +        String uuid = idNode.textValue();
-         assertNotNull(uuid);
+         assertNotNull( uuid );
 -        logNode( node );
  
          byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
--        resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
++        resource().path( orgAppPath + "/foos/" + uuid ).queryParam( "access_token", access_token )
                  .type( MediaType.APPLICATION_OCTET_STREAM_TYPE ).put( data );
  
          // get entity
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON_TYPE ).get( JsonNode.class );
 -        logNode( node );
 -        Assert.assertEquals( "image/jpeg", node.findValue( AssetUtils.CONTENT_TYPE ).getTextValue() );
 -        Assert.assertEquals( 7979, node.findValue( "content-length" ).getIntValue() );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid ).queryParam( "access_token", access_token )
 +                .accept( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
 +        Assert.assertEquals( "image/jpeg", node.findValue( AssetUtils.CONTENT_TYPE ).textValue() );
 +        Assert.assertEquals( 7979, node.findValue( "content-length" ).intValue() );
          idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        assertEquals( uuid, idNode.getTextValue() );
 +        assertEquals( uuid, idNode.textValue() );
  
          // get data by UUID
          InputStream is =
--                resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
++                resource().path( orgAppPath + "/foos/" + uuid ).queryParam( "access_token", access_token )
                          .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE ).get( InputStream.class );
  
          byte[] foundData = IOUtils.toByteArray( is );
          assertEquals( 7979, foundData.length );
  
 +        refreshIndex();
 +
          // get data by name
--        is = resource().path( "/test-organization/test-app/foos/assetname" ).queryParam( "access_token", access_token )
++        is = resource().path( orgAppPath + "/foos/assetname" ).queryParam( "access_token", access_token )
                  .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE ).get( InputStream.class );
  
          foundData = IOUtils.toByteArray( is );
@@@ -144,52 -136,83 +148,73 @@@
  
      @Test
      public void multipartPostFormOnDynamicEntity() throws Exception {
 -        UserRepo.INSTANCE.load( resource(), access_token );
 +
++        this.refreshIndex();
+ 
          byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/file-bigger-than-5M" ) );
 +        FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
  
-         JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA )
-                 .post( String.class, form ));
 -        FormDataMultiPart form = new FormDataMultiPart()
 -                .field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
+ 
 -        JsonNode node = resource().path( "/test-organization/test-app/foos" )
 -                .queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON )
 -                .type( MediaType.MULTIPART_FORM_DATA )
 -                .post( JsonNode.class, form );
++        JsonNode node = mapper.readTree( resource().path( orgAppPath + "/foos" )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON )
++            .type( MediaType.MULTIPART_FORM_DATA )
++            .post( String.class, form ));
  
          JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        String uuid = idNode.getTextValue();
 -        assertNotNull( uuid );
 -        logNode( node );
 +        String uuid = idNode.textValue();
 +        assertNotNull(uuid);
  
--        // get entity
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
-         assertEquals( "application/octet-stream", node.findValue( AssetUtils.CONTENT_TYPE ).textValue() );
-         assertEquals( 5324800, node.findValue( AssetUtils.CONTENT_LENGTH ).intValue() );
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid )
 -                .queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON_TYPE )
 -                .get( JsonNode.class );
 -
 -        logNode( node );
 -        assertEquals( "application/octet-stream", node.findValue( AssetUtils.CONTENT_TYPE ).getTextValue() );
 -        assertEquals( 5324800, node.findValue( AssetUtils.CONTENT_LENGTH ).getIntValue() );
--        idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
-         assertEquals( uuid, idNode.textValue() );
 -        assertEquals( uuid, idNode.getTextValue() );
++        this.refreshIndex();
  
-         // get data
-         InputStream is =
-                 resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                         .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE ).get( InputStream.class );
+         int retries = 0;
+         boolean done = false;
+         byte[] foundData = new byte[0];
+ 
+         // retry until upload complete
+         while ( !done && retries < 30 ) {
+ 
+             // get data
+             try {
 -                InputStream is = resource().path( "/test-organization/test-app/foos/" + uuid )
++                InputStream is = resource().path( orgAppPath + "/foos/" + uuid )
+                         .queryParam( "access_token", access_token )
+                         .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE )
+                         .get( InputStream.class );
+ 
+                 foundData = IOUtils.toByteArray( is );
+                 done = true;
+ 
+             } catch ( Exception intentiallyIgnored ) {}
+ 
+             Thread.sleep(1000);
+             retries++;
+         }
  
-         byte[] foundData = IOUtils.toByteArray( is );
          assertEquals( 5324800, foundData.length );
  
          // delete
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid )
 -                .queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON_TYPE )
 -                .delete( JsonNode.class );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid ).queryParam( "access_token", access_token )
 +                .accept( MediaType.APPLICATION_JSON_TYPE ).delete( String.class ));
      }
  
  
      @Test
      public void multipartPutFormOnDynamicEntity() throws Exception {
 -        UserRepo.INSTANCE.load( resource(), access_token );
 +
++        this.refreshIndex();
+ 
          Map<String, String> payload = hashMap( "foo", "bar" );
  
-         JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
 -        JsonNode node = resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
++        JsonNode node = mapper.readTree( resource().path( orgAppPath + "/foos" ).queryParam( "access_token", access_token )
                  .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
 -                .post( JsonNode.class, payload );
 +                .post( String.class, payload ));
  
          JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        String uuid = idNode.getTextValue();
 +        String uuid = idNode.textValue();
-         assertNotNull(uuid);
+         assertNotNull( uuid );
 -        logNode( node );
  
          // set file & assetname
          byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
@@@ -197,58 -220,63 +222,77 @@@
                                                          .field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
  
          long created = System.currentTimeMillis();
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA ).put( String.class, form ));
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA ).put( JsonNode.class, form );
 -        logNode( node );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON )
++            .type( MediaType.MULTIPART_FORM_DATA )
++            .put( String.class, form ));
++
++        this.refreshIndex();
  
          // get entity
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON_TYPE ).get( String.class ));
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON_TYPE ).get( JsonNode.class );
 -        logNode( node );
 -        assertEquals( "image/jpeg", node.findValue( AssetUtils.CONTENT_TYPE ).getTextValue() );
 -        assertEquals( 7979, node.findValue( AssetUtils.CONTENT_LENGTH ).getIntValue() );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON_TYPE )
++            .get( String.class ));
++        LOG.debug( mapToFormattedJsonString(node) );
++
 +        assertEquals( "image/jpeg", node.findValue( AssetUtils.CONTENT_TYPE ).textValue() );
 +        assertEquals( 7979, node.findValue( AssetUtils.CONTENT_LENGTH ).intValue() );
          idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        assertEquals( uuid, idNode.getTextValue() );
 +        assertEquals( uuid, idNode.textValue() );
          JsonNode nameNode = node.get( "entities" ).get( 0 ).get( "foo" );
 -        assertEquals( "bar2", nameNode.getTextValue() );
 -        long lastModified = node.findValue( AssetUtils.LAST_MODIFIED ).getLongValue();
 +        assertEquals( "bar2", nameNode.textValue() );
 +        long lastModified = node.findValue( AssetUtils.LAST_MODIFIED ).longValue();
          Assert.assertEquals( created, lastModified, 500 );
  
          // get data
--        InputStream is =
--                resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
--                        .accept( "image/jpeg" ).get( InputStream.class );
++        InputStream is = resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( "image/jpeg" )
++            .get( InputStream.class );
  
          byte[] foundData = IOUtils.toByteArray( is );
          assertEquals( 7979, foundData.length );
  
          // post new data
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA ).put( String.class, form ));
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA ).put( JsonNode.class, form );
 -        logNode( node );
 -        assertTrue( lastModified != node.findValue( AssetUtils.LAST_MODIFIED ).getLongValue() );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON )
++            .type( MediaType.MULTIPART_FORM_DATA )
++            .put( String.class, form ) );
 +        Assert.assertTrue( lastModified != node.findValue( AssetUtils.LAST_MODIFIED ).longValue() );
      }
  
  
      @Test
-     @Ignore("Just enable and run when testing S3 large file upload specifically")
      public void largeFileInS3() throws Exception {
 -        UserRepo.INSTANCE.load( resource(), access_token );
 +
++        this.refreshIndex();
+ 
          byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/file-bigger-than-5M" ) );
          FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
  
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
          // send data
-         JsonNode node = mapper.readTree( resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
 -        JsonNode node = resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
--                .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA )
-                 .post( String.class, form ));
 -                .post( JsonNode.class, form );
 -        logNode( node );
++        JsonNode node = mapper.readTree( resource().path( orgAppPath + "/foos" )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON )
++            .type( MediaType.MULTIPART_FORM_DATA )
++            .post( String.class, form ) );
          JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -        String uuid = idNode.getTextValue();
 +        String uuid = idNode.textValue();
  
          // get entity
          long timeout = System.currentTimeMillis() + 60000;
          while ( true ) {
-             LOG.info("Waiting for upload to finish...");
+             LOG.info( "Waiting for upload to finish..." );
              Thread.sleep( 2000 );
-             node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid )
 -            node = resource().path( "/test-organization/test-app/foos/" + uuid )
--                    .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
-                     .get( String.class ));
 -                    .get( JsonNode.class );
 -            logNode( node );
++            node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid )
++                .queryParam( "access_token", access_token )
++                .accept( MediaType.APPLICATION_JSON_TYPE )
++                .get( String.class ) );
  
              // poll for the upload to complete
              if ( node.findValue( AssetUtils.E_TAG ) != null ) {
@@@ -261,18 -289,75 +305,82 @@@
          LOG.info( "Upload complete!" );
  
          // get data
--        InputStream is =
--                resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
--                        .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE ).get( InputStream.class );
++        InputStream is = resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_OCTET_STREAM_TYPE )
++            .get( InputStream.class );
  
          byte[] foundData = IOUtils.toByteArray( is );
--        assertEquals( 5324800, foundData.length );
++        assertEquals( data.length, foundData.length );
  
          // delete
-         node = mapper.readTree( resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
-                 .accept( MediaType.APPLICATION_JSON_TYPE ).delete( String.class ));
 -        node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
 -                .accept( MediaType.APPLICATION_JSON_TYPE ).delete( JsonNode.class );
++        node = mapper.readTree( resource().path( orgAppPath + "/foos/" + uuid )
++            .queryParam( "access_token", access_token )
++            .accept( MediaType.APPLICATION_JSON_TYPE )
++            .delete( String.class ) );
      }
  
+     @Test
+     public void fileTooLargeShouldResultInError() throws Exception {
+ 
++        this.refreshIndex();
++
+         Map<String, String> props = new HashMap<String, String>();
+         props.put( "usergrid.binary.max-size-mb", "6" );
+         resource().path( "/testproperties" )
+                 .queryParam( "access_token", access_token )
+                 .accept( MediaType.APPLICATION_JSON )
+                 .type( MediaType.APPLICATION_JSON_TYPE ).post( props );
+ 
+         try {
+ 
 -            UserRepo.INSTANCE.load( resource(), access_token );
++            //UserRepo.INSTANCE.load( resource(), access_token );
+ 
+             byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cat-larger-than-6mb.jpg" ) );
+             FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+ 
++            String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
+             // send data
 -            JsonNode node = resource().path( "/test-organization/test-app/bars" ).queryParam( "access_token", access_token )
++            JsonNode node = resource().path( orgAppPath + "/bars" ).queryParam( "access_token", access_token )
+                     .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA )
+                     .post( JsonNode.class, form );
+             //logNode( node );
+             JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
 -            String uuid = idNode.getTextValue();
++            String uuid = idNode.textValue();
+ 
+             // get entity
+             String errorMessage = null;
+             long timeout = System.currentTimeMillis() + 60000;
+             while (true) {
+                 LOG.info( "Waiting for upload to finish..." );
+                 Thread.sleep( 2000 );
 -                node = resource().path( "/test-organization/test-app/bars/" + uuid )
++                node = resource().path( orgAppPath + "/bars/" + uuid )
+                         .queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
+                         .get( JsonNode.class );
+                 //logNode( node );
+ 
+                 // poll for the error to happen
+                 if (node.findValue( "error" ) != null) {
+                     errorMessage = node.findValue("error").asText();
+                     break;
+                 }
+                 if (System.currentTimeMillis() > timeout) {
+                     throw new TimeoutException();
+                 }
+             }
+ 
+             assertTrue( errorMessage.startsWith("Asset size "));
+ 
+         } finally {
+             props = new HashMap<String, String>();
+             props.put( "usergrid.binary.max-size-mb", "25" );
+             resource().path( "/testproperties" )
+                     .queryParam( "access_token", access_token )
+                     .accept( MediaType.APPLICATION_JSON )
+                     .type( MediaType.APPLICATION_JSON_TYPE ).post( props );
+         }
+     }
  
      /**
       * Deleting a connection to an asset should not delete the asset or the asset's data
@@@ -280,26 -365,26 +388,30 @@@
      @Test
      public void deleteConnectionToAsset() throws IOException {
  
-         userRepo.load();
 -        UserRepo.INSTANCE.load( resource(), access_token );
++        this.refreshIndex();
  
          final String uuid;
  
++        access_token = this.getAdminToken().getAccessToken();
++
++        String orgAppPath = clientSetup.getOrganizationName() + "/" + clientSetup.getAppName();
++
          // create the entity that will be the asset, an image
  
          Map<String, String> payload = hashMap("name", "cassandra_eye.jpg");
--
-         JsonNode node = resource().path("/test-organization/test-app/foos")
 -        JsonNode node = resource().path("/test-organization/test-app/bars")
--                .queryParam("access_token", access_token)
--                .accept(MediaType.APPLICATION_JSON)
--                .type(MediaType.APPLICATION_JSON_TYPE)
--                .post(JsonNode.class, payload);
++        JsonNode node = resource().path(orgAppPath + "/foos")
++            .header( "Authorization", "Bearer " + access_token )
++            //.queryParam("access_token", access_token)
++            .accept( MediaType.APPLICATION_JSON )
++            .type( MediaType.APPLICATION_JSON_TYPE )
++            .post(JsonNode.class, payload);
          JsonNode idNode = node.get("entities").get(0).get("uuid");
 -        uuid = idNode.getTextValue();
 +        uuid = idNode.textValue();
  
          // post image data to the asset entity
  
          byte[] data = IOUtils.toByteArray(this.getClass().getResourceAsStream("/cassandra_eye.jpg"));
--        resource().path("/test-organization/test-app/foos/" + uuid)
++        resource().path(orgAppPath + "/foos/" + uuid)
                  .queryParam("access_token", access_token)
                  .type(MediaType.APPLICATION_OCTET_STREAM_TYPE)
                  .put(data);
@@@ -308,7 -393,7 +420,7 @@@
  
          Map<String, String> imageGalleryPayload = hashMap("name", "my image gallery");
  
--        JsonNode imageGalleryNode = resource().path("/test-organization/test-app/imagegalleries")
++        JsonNode imageGalleryNode = resource().path(orgAppPath + "/imagegalleries")
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON)
                  .type(MediaType.APPLICATION_JSON_TYPE)
@@@ -320,34 -405,34 +432,40 @@@
          // connect imagegallery to asset
  
          JsonNode connectNode = resource()
--                .path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
++                .path(orgAppPath + "/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON)
                  .type(MediaType.APPLICATION_JSON_TYPE)
                  .post(JsonNode.class);
++        LOG.debug( mapToFormattedJsonString(connectNode) );
++
++        this.refreshIndex();
  
          // verify connection from imagegallery to asset
  
          JsonNode listConnectionsNode = resource()
--                .path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/")
++                .path(orgAppPath + "/imagegalleries/" + imageGalleryId + "/contains/")
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON)
                  .type(MediaType.APPLICATION_JSON_TYPE)
                  .get(JsonNode.class);
 -        assertEquals(uuid, listConnectionsNode.get("entities").get(0).get("uuid").getTextValue());
++        LOG.debug( mapToFormattedJsonString(listConnectionsNode) );
 +        assertEquals(uuid, listConnectionsNode.get("entities").get(0).get("uuid").textValue());
  
          // delete the connection
  
--        resource().path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
++        resource().path(orgAppPath + "/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON)
                  .type(MediaType.APPLICATION_JSON_TYPE)
                  .delete();
  
++        this.refreshIndex();
++
          // verify that connection is gone
  
          listConnectionsNode = resource()
--                .path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/")
++                .path(orgAppPath + "/imagegalleries/" + imageGalleryId + "/contains/")
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON)
                  .type(MediaType.APPLICATION_JSON_TYPE)
@@@ -356,7 -441,7 +474,7 @@@
  
          // asset should still be there
  
--        JsonNode assetNode = resource().path("/test-organization/test-app/foos/" + uuid)
++        JsonNode assetNode = resource().path(orgAppPath + "/foos/" + uuid)
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_JSON_TYPE)
                  .get(JsonNode.class);
@@@ -368,7 -454,7 +486,7 @@@
  
          // asset data should still be there
  
--        InputStream assetIs = resource().path("/test-organization/test-app/foos/" + uuid)
++        InputStream assetIs = resource().path(orgAppPath + "/foos/" + uuid)
                  .queryParam("access_token", access_token)
                  .accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
                  .get(InputStream.class);

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/a7840164/stack/rest/src/test/java/org/apache/usergrid/rest/applications/utils/UserRepo.java
----------------------------------------------------------------------
diff --cc stack/rest/src/test/java/org/apache/usergrid/rest/applications/utils/UserRepo.java
index 06c3a76,993b30f..fd948aa
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/utils/UserRepo.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/utils/UserRepo.java
@@@ -17,31 -17,22 +17,24 @@@
  package org.apache.usergrid.rest.applications.utils;
  
  
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.sun.jersey.api.client.WebResource;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.UUID;
- import java.util.logging.Level;
- import java.util.logging.Logger;
- import javax.ws.rs.core.MediaType;
- import static org.apache.usergrid.utils.MapUtils.hashMap;
- 
- import org.apache.usergrid.rest.test.resource2point0.AbstractRestIT;
 +import org.apache.usergrid.rest.test.resource2point0.ClientSetup;
 +import org.apache.usergrid.rest.test.resource2point0.model.Entity;
 +import org.apache.usergrid.utils.UUIDUtils;
 +
+ import java.util.HashMap;
+ import java.util.Map;
+ import java.util.UUID;
  
- public class UserRepo {
 -import javax.ws.rs.core.MediaType;
 -
 -import org.codehaus.jackson.JsonNode;
 -import org.apache.usergrid.utils.UUIDUtils;
 -
 -import com.sun.jersey.api.client.WebResource;
 -
 -import static org.apache.usergrid.utils.MapUtils.hashMap;
  
++/**
++ * Creates three users in current app
++ */
++public class UserRepo {
 +    private final ClientSetup clientSetup;
  
 -public enum UserRepo {
 -    INSTANCE;
 +    public UserRepo(ClientSetup clientSetup){
 +        this.clientSetup =  clientSetup;
 +    }
  
      private final Map<String, UUID> loaded = new HashMap<String, UUID>();
  
@@@ -49,42 -41,41 +42,31 @@@
          if ( loaded.size() > 0 ) {
              return;
          }
- 
-         // pause between creation to insure entities are created in order
--
 -        createUser( "user1", "user1@apigee.com", "user1", "Jane Smith 1", resource, accessToken );
 -        createUser( "user2", "user2@apigee.com", "user2", "John Smith 2", resource, accessToken );
 -        createUser( "user3", "user3@apigee.com", "user3", "John Smith 3", resource, accessToken );
 +        createUser( "user1", "user1@apigee.com", "user1", "Jane Smith 1" );
- 
 +        createUser( "user2", "user2@apigee.com", "user2", "John Smith 2" );
- 
 +        createUser( "user3", "user3@apigee.com", "user3", "John Smith 3"  );
      }
  
 -
 -    private void createUser( String username, String email, String password, String fullName, WebResource resource,
 -                             String accessToken ) {
 -
 -        Map<String, String> payload = hashMap( "email", email ).map( "username", username ).map( "name", fullName )
 -                .map( "password", password ).map( "pin", "1234" );
 -
 -        UUID id = createUser( payload, resource, accessToken );
--
 +    private void createUser( String username, String email, String password, String fullName) {
 +        Entity entity = new Entity();
 +        entity.put( "email", email );
 +        entity.put( "username", username );
 +        entity.put("name", fullName);
 +        entity.put( "password", password );
 +        entity.put("pin", "1234");
 +        UUID id = createUser( entity );
          loaded.put( username, id );
      }
  
--
      public UUID getByUserName( String name ) {
          return loaded.get( name );
      }
  
--
      /** Create a user via the REST API and post it. Return the response */
 -    private UUID createUser( Map<String, String> payload, WebResource resource, String access_token ) {
 -
 -        JsonNode response =
 -                resource.path( "/test-organization/test-app/users" ).queryParam( "access_token", access_token )
 -                        .accept( MediaType.APPLICATION_JSON ).type( MediaType.APPLICATION_JSON_TYPE )
 -                        .post( JsonNode.class, payload );
 -
 -        String idString = response.get( "entities" ).get( 0 ).get( "uuid" ).asText();
 -
 +    private UUID createUser( Entity payload )  {
- 
-         Entity entity =  clientSetup.getRestClient().org(clientSetup.getOrganizationName()).app(clientSetup.getAppName()).collection("users").post(payload);
- 
++        Entity entity =  clientSetup.getRestClient().org(
++            clientSetup.getOrganizationName()).app(clientSetup.getAppName()).collection("users").post(payload);
 +        String idString = entity.get("uuid").toString();
- 
          return UUIDUtils.tryExtractUUID( idString );
      }
--
  }