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

[02/11] incubator-usergrid git commit: Added properties and tests for the future asset stuff.

Added properties and tests for the future asset stuff.


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

Branch: refs/heads/two-dot-o-dev
Commit: ca8d1c32597c857df6310dca680bd8041029771e
Parents: 915055b
Author: GERey <gr...@apigee.com>
Authored: Wed Jul 22 14:04:35 2015 -0700
Committer: GERey <gr...@apigee.com>
Committed: Wed Jul 22 14:04:35 2015 -0700

----------------------------------------------------------------------
 .../main/resources/usergrid-default.properties  |   4 +
 .../persistence/queue/QueueManagerTest.java     |   2 +-
 .../rest/applications/ServiceResource.java      |  22 +-
 .../applications/assets/AssetResourceIT.java    |   4 +
 .../applications/assets/AwsAssetResourceIT.java | 352 +++++++++++++++++++
 .../applications/assets/aws/NoAWSCredsRule.java |  98 ++++++
 .../rest/management/RegistrationIT.java         |  27 --
 .../rest/test/resource/AbstractRestIT.java      |  36 +-
 .../management/AccountCreationProps.java        |   2 +
 9 files changed, 515 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/config/src/main/resources/usergrid-default.properties
----------------------------------------------------------------------
diff --git a/stack/config/src/main/resources/usergrid-default.properties b/stack/config/src/main/resources/usergrid-default.properties
index 80e5503..0f46172 100644
--- a/stack/config/src/main/resources/usergrid-default.properties
+++ b/stack/config/src/main/resources/usergrid-default.properties
@@ -481,6 +481,10 @@ usergrid.binary.bucketname=usergrid-binaries
 #
 usergrid.temp.files=/tmp/usergrid
 
+# Set the implementation of binary uploading to be used
+# Aws for aws s3 uploading, local
+usergrid.binary.uploader=local
+
 
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/QueueManagerTest.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/QueueManagerTest.java b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/QueueManagerTest.java
index 0ed6065..3be02e1 100644
--- a/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/QueueManagerTest.java
+++ b/stack/corepersistence/queue/src/test/java/org/apache/usergrid/persistence/queue/QueueManagerTest.java
@@ -53,7 +53,7 @@ public class QueueManagerTest {
     protected QueueManagerFactory qmf;
 
     /**
-     * Mark tests as ignored if now AWS creds are present
+     * Mark tests as ignored if no AWS creds are present
      */
     @Rule
     public NoAWSCredsRule awsCredsRule = new NoAWSCredsRule();

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
index c6dbcf0..fc729d4 100644
--- a/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
+++ b/stack/rest/src/main/java/org/apache/usergrid/rest/applications/ServiceResource.java
@@ -68,7 +68,9 @@ import org.apache.usergrid.services.ServicePayload;
 import org.apache.usergrid.services.ServiceRequest;
 import org.apache.usergrid.services.ServiceResults;
 import org.apache.usergrid.services.assets.data.AssetUtils;
+import org.apache.usergrid.services.assets.data.AwsSdkS3BinaryStore;
 import org.apache.usergrid.services.assets.data.BinaryStore;
+import org.apache.usergrid.services.assets.data.LocalFileBinaryStore;
 import org.apache.usergrid.utils.InflectionUtils;
 import org.apache.usergrid.utils.JsonUtils;
 
@@ -94,9 +96,15 @@ public class ServiceResource extends AbstractContextResource {
     private static final String FILE_FIELD_NAME = "file";
 
 
-    @Autowired
+   // @Autowired
     private BinaryStore binaryStore;
 
+    @Autowired
+    private LocalFileBinaryStore localFileBinaryStore;
+
+    @Autowired
+    private AwsSdkS3BinaryStore awsSdkS3BinaryStore;
+
     protected ServiceManager services;
 
     List<ServiceParameter> serviceParameters = null;
@@ -106,6 +114,18 @@ public class ServiceResource extends AbstractContextResource {
     }
 
 
+    public void setBinaryStore(String binaryStoreType){
+
+        //TODO:GREY change this to be a property held elsewhere
+        if(binaryStoreType.equals("local")){
+            this.binaryStore = localFileBinaryStore;
+        }
+        else{
+            this.binaryStore = awsSdkS3BinaryStore;
+        }
+    }
+
+
     @Override
     public void setParent( AbstractContextResource parent ) {
         super.setParent( parent );

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AssetResourceIT.java
----------------------------------------------------------------------
diff --git 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
index 616d163..65c6d52 100644
--- 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
@@ -19,12 +19,15 @@ package org.apache.usergrid.rest.applications.assets;
 
 import com.sun.jersey.multipart.FormDataMultiPart;
 import org.apache.commons.io.IOUtils;
+
+import org.apache.usergrid.rest.applications.ServiceResource;
 import org.apache.usergrid.rest.test.resource.AbstractRestIT;
 import org.apache.usergrid.rest.test.resource.model.ApiResponse;
 import org.apache.usergrid.rest.test.resource.model.Entity;
 import org.apache.usergrid.services.assets.data.AssetUtils;
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,6 +51,7 @@ public class AssetResourceIT extends AbstractRestIT {
     @Before
     public void setup(){
         access_token = this.getAdminToken().getAccessToken();
+
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AwsAssetResourceIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AwsAssetResourceIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AwsAssetResourceIT.java
new file mode 100644
index 0000000..1bd8dc1
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/AwsAssetResourceIT.java
@@ -0,0 +1,352 @@
+/*
+ * 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.rest.applications.assets;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.blobstore.BlobStoreContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.usergrid.cassandra.SpringResource;
+import org.apache.usergrid.management.ManagementService;
+import org.apache.usergrid.rest.applications.assets.aws.NoAWSCredsRule;
+import org.apache.usergrid.rest.test.resource.AbstractRestIT;
+import org.apache.usergrid.rest.test.resource.model.ApiResponse;
+import org.apache.usergrid.rest.test.resource.model.Entity;
+import org.apache.usergrid.services.assets.data.AssetUtils;
+import org.apache.usergrid.services.assets.data.BinaryStore;
+import org.apache.usergrid.setup.ConcurrentProcessSingleton;
+
+import com.sun.jersey.multipart.FormDataMultiPart;
+
+import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_SYSADMIN_EMAIL;
+import static org.apache.usergrid.management.AccountCreationProps.PROPERTIES_USERGRID_BINARY_UPLOADER;
+import static org.apache.usergrid.utils.MapUtils.hashMap;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+
+
+public class AwsAssetResourceIT extends AbstractRestIT {
+
+    private String access_token;
+    private Map<String, Object> originalProperties;
+    private Logger LOG = LoggerFactory.getLogger( AwsAssetResourceIT.class );
+
+//    /**
+//     * Mark tests as ignored if no AWS creds are present
+//     */
+//    @Rule
+//    public NoAWSCredsRule awsCredsRule = new NoAWSCredsRule();
+
+    @Before
+    public void setup(){
+        Map<String, Object> originalProperties = getRemoteTestProperties();
+        setTestProperty(PROPERTIES_USERGRID_BINARY_UPLOADER, "AWS");
+
+
+        access_token = this.getAdminToken().getAccessToken();
+
+    }
+
+    @After
+    public void teardown(){
+        setTestProperties(originalProperties);
+    }
+
+    @Test
+    public void octetStreamOnDynamicEntity() throws Exception {
+
+        this.refreshIndex();
+
+        //  post an asset entity
+
+        Map<String, String> payload = hashMap( "name", "assetname" );
+        ApiResponse postResponse = pathResource( getOrgAppPath( "foos" )).post( payload );
+        UUID assetId = postResponse.getEntities().get(0).getUuid();
+        assertNotNull(assetId);
+
+        // post a binary asset to that entity
+
+        byte[] data = IOUtils.toByteArray( getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
+        ApiResponse putResponse = pathResource( getOrgAppPath("foos/" + assetId) )
+            .put( data, MediaType.APPLICATION_OCTET_STREAM_TYPE );
+
+        // check that the asset entity has asset metadata
+
+        ApiResponse getResponse = pathResource( getOrgAppPath( "foos/" + assetId) ).get( ApiResponse.class );
+        Entity entity = getResponse.getEntities().get(0);
+        Map<String, Object> fileMetadata = (Map<String, Object>)entity.get("file-metadata");
+        Assert.assertEquals( "image/jpeg", fileMetadata.get( "content-type" ) );
+        Assert.assertEquals( 7979,         fileMetadata.get( "content-length" ));
+        assertEquals( assetId, entity.getUuid() );
+
+        // get binary asset by UUID
+
+        InputStream is = pathResource( getOrgAppPath("foos/" + assetId) ).getAssetAsStream();
+        byte[] foundData = IOUtils.toByteArray( is );
+        assertEquals( 7979, foundData.length );
+
+        // get binary asset by name
+
+        is = pathResource( getOrgAppPath("foos/assetname") ).getAssetAsStream();
+        foundData = IOUtils.toByteArray( is );
+        assertEquals( 7979, foundData.length );
+    }
+
+
+    @Test
+    public void multipartPostFormOnDynamicEntity() throws Exception {
+
+        this.refreshIndex();
+
+        // post data larger than 5M
+
+        byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/file-bigger-than-5M" ) );
+        FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+        ApiResponse putResponse = pathResource(getOrgAppPath("foos")).post(form);
+        this.refreshIndex();
+
+        UUID assetId = putResponse.getEntities().get(0).getUuid();
+        assertNotNull(assetId);
+
+        // retry until upload complete and we can get the data
+
+        int retries = 0;
+        boolean done = false;
+        byte[] foundData = new byte[0];
+        while ( !done && retries < 30 ) {
+
+            try {
+                InputStream is = pathResource( getOrgAppPath( "foos/" + assetId ) ).getAssetAsStream();
+                foundData = IOUtils.toByteArray( is );
+                done = true;
+
+            } catch ( Exception intentiallyIgnored ) {}
+
+            Thread.sleep(1000);
+            retries++;
+        }
+
+        //  did we get expected number of bytes of data?
+
+        assertEquals( 5324800, foundData.length );
+
+        pathResource( getOrgAppPath( "foos/" + assetId ) ).delete();
+    }
+
+
+    @Test
+    public void multipartPutFormOnDynamicEntity() throws Exception {
+
+        this.refreshIndex();
+
+        // post an entity
+
+        Map<String, String> payload = hashMap( "foo", "bar" );
+        ApiResponse postResponse = pathResource( getOrgAppPath( "foos" ) ).post( payload );
+        UUID assetId = postResponse.getEntities().get(0).getUuid();
+        assertNotNull( assetId );
+
+        // post asset to that entity
+
+        byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
+        FormDataMultiPart form = new FormDataMultiPart()
+            .field( "foo", "bar2" )
+            .field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+        ApiResponse putResponse = pathResource( getOrgAppPath( "foos/" + assetId ) ).put( form );
+        this.refreshIndex();
+
+        // get entity and check asset metadata
+
+        ApiResponse getResponse = pathResource( getOrgAppPath( "foos/" + assetId ) ).get( ApiResponse.class );
+        Entity entity = getResponse.getEntities().get( 0 );
+        Map<String, Object> fileMetadata = (Map<String, Object>)entity.get("file-metadata");
+        long lastModified = Long.parseLong( fileMetadata.get( AssetUtils.LAST_MODIFIED ).toString() );
+
+        assertEquals( assetId,      entity.getUuid() );
+        assertEquals( "bar2",       entity.get("foo") );
+        assertEquals( "image/jpeg", fileMetadata.get( AssetUtils.CONTENT_TYPE ) );
+        assertEquals( 7979,         fileMetadata.get( AssetUtils.CONTENT_LENGTH ));
+
+        // get asset and check size
+
+        InputStream is = pathResource( getOrgAppPath( "foos/" + assetId ) ).getAssetAsStream();
+        byte[] foundData = IOUtils.toByteArray( is );
+        assertEquals( 7979, foundData.length );
+
+        // upload new asset to entity, then check that it was updated
+
+        ApiResponse putResponse2 = pathResource( getOrgAppPath( "foos/" + assetId ) ).put( form );
+        entity = putResponse2.getEntities().get( 0 );
+        fileMetadata = (Map<String, Object>)entity.get("file-metadata");
+        long justModified = Long.parseLong( fileMetadata.get( AssetUtils.LAST_MODIFIED ).toString() );
+        assertNotEquals( lastModified, justModified );
+    }
+
+
+    @Test
+    public void largeFileInS3() throws Exception {
+
+        this.refreshIndex();
+
+        // upload file larger than 5MB
+
+        byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/file-bigger-than-5M" ) );
+        FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+        ApiResponse postResponse = pathResource( getOrgAppPath( "foos" ) ).post( form );
+        UUID assetId = postResponse.getEntities().get(0).getUuid();
+        LOG.info( "Waiting for upload to finish..." );
+        Thread.sleep( 2000 );
+
+        // check that entire file was uploaded
+
+        ApiResponse getResponse = pathResource( getOrgAppPath( "foos/" +assetId ) ).get( ApiResponse.class );
+        LOG.info( "Upload complete!" );
+        InputStream is = pathResource( getOrgAppPath( "foos/" + assetId ) ).getAssetAsStream();
+        byte[] foundData = IOUtils.toByteArray( is );
+        assertEquals( data.length, foundData.length );
+
+        // delete file
+
+        pathResource( getOrgAppPath( "foos/" + assetId ) ).delete();
+    }
+
+    @Test
+    public void fileTooLargeShouldResultInError() throws Exception {
+
+        this.refreshIndex();
+
+        // set max file size down to 6mb
+
+        Map<String, String> props = new HashMap<String, String>();
+        props.put( "usergrid.binary.max-size-mb", "6" );
+        pathResource( "testproperties" ).post( props );
+
+        try {
+
+            // upload a file larger than 6mb
+
+            byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cat-larger-than-6mb.jpg" ) );
+            FormDataMultiPart form = new FormDataMultiPart().field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+            ApiResponse postResponse = pathResource( getOrgAppPath( "bars" ) ).post( form );
+            UUID assetId = postResponse.getEntities().get(0).getUuid();
+
+            String errorMessage = null;
+            LOG.info( "Waiting for upload to finish..." );
+            Thread.sleep( 2000 );
+
+            // attempt to get asset entity, it should contain error
+
+            ApiResponse getResponse = pathResource( getOrgAppPath( "bars/" +assetId ) ).get( ApiResponse.class );
+            Map<String, Object> fileMetadata = (Map<String, Object>)getResponse.getEntities().get(0).get("file-metadata");
+            assertTrue( fileMetadata.get( "error" ).toString().startsWith( "Asset size " ) );
+
+        } finally {
+
+            // set max upload size back to default 25mb
+
+            props.put( "usergrid.binary.max-size-mb", "25" );
+            pathResource( "testproperties" ).post( props );
+        }
+    }
+
+    /**
+     * Deleting a connection to an asset should not delete the asset or the asset's data
+     */
+    @Test
+    public void deleteConnectionToAsset() throws IOException {
+
+        this.refreshIndex();
+
+        // create the entity that will be the asset, an image
+
+        Map<String, String> payload = hashMap("name", "cassandra_eye.jpg");
+        ApiResponse postReponse = pathResource( getOrgAppPath( "foos" ) ).post( payload );
+        final UUID uuid = postReponse.getEntities().get(0).getUuid();
+
+        // post image data to the asset entity
+
+        byte[] data = IOUtils.toByteArray(this.getClass().getResourceAsStream("/cassandra_eye.jpg"));
+        pathResource( getOrgAppPath( "foos/" + uuid ) ).put( data, MediaType.APPLICATION_OCTET_STREAM_TYPE );
+
+        // create an imagegallery entity
+
+        Map<String, String> imageGalleryPayload = hashMap("name", "my image gallery");
+
+        ApiResponse postResponse2 = pathResource( getOrgAppPath( "imagegalleries" ) ).post( imageGalleryPayload );
+        UUID imageGalleryId = postResponse2.getEntities().get(0).getUuid();
+
+        // connect imagegallery to asset
+
+        ApiResponse connectResponse = pathResource(
+            getOrgAppPath( "imagegalleries/" + imageGalleryId + "/contains/" + uuid ) ).post( ApiResponse.class );
+        this.refreshIndex();
+
+        // verify connection from imagegallery to asset
+
+        ApiResponse containsResponse = pathResource(
+            getOrgAppPath( "imagegalleries/" + imageGalleryId + "/contains/" ) ).get( ApiResponse.class );
+        assertEquals( uuid, containsResponse.getEntities().get(0).getUuid() );
+
+        // delete the connection
+
+        pathResource( getOrgAppPath( "imagegalleries/" + imageGalleryId + "/contains/" + uuid ) ).delete();
+        this.refreshIndex();
+
+        // verify that connection is gone
+
+        ApiResponse listResponse = pathResource(
+            getOrgAppPath( "imagegalleries/" + imageGalleryId + "/contains/" )).get( ApiResponse.class );
+        assertEquals( 0, listResponse.getEntityCount() );
+
+        // asset should still be there
+
+        ApiResponse getResponse2 = pathResource( getOrgAppPath( "foos/" + uuid ) ).get( ApiResponse.class );
+        Entity entity = getResponse2.getEntities().get(0);
+        Map<String, Object> fileMetadata = (Map<String, Object>)entity.get("file-metadata");
+
+        Assert.assertEquals("image/jpeg", fileMetadata.get( AssetUtils.CONTENT_TYPE ));
+        Assert.assertEquals(7979, fileMetadata.get( AssetUtils.CONTENT_LENGTH ));
+        assertEquals(uuid, entity.getUuid());
+
+        // asset data should still be there
+
+        InputStream assetIs = pathResource( getOrgAppPath( "foos/" + uuid ) ).getAssetAsStream();
+        byte[] foundData = IOUtils.toByteArray(assetIs);
+        assertEquals(7979, foundData.length);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/aws/NoAWSCredsRule.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/aws/NoAWSCredsRule.java b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/aws/NoAWSCredsRule.java
new file mode 100644
index 0000000..fe49d6c
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/assets/aws/NoAWSCredsRule.java
@@ -0,0 +1,98 @@
+/*
+ * 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.rest.applications.assets.aws;
+
+
+import org.junit.Assume;
+import org.junit.internal.runners.model.MultipleFailureException;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import com.amazonaws.AmazonClientException;
+
+
+/**
+ * Created in an attempt to mark no aws cred tests as ignored.  Blocked by this issue
+ * https://github.com/junit-team/junit/issues/116
+ *
+ * Until then, simply marks as passed, which is a bit dangerous
+ */
+public class NoAWSCredsRule implements TestRule {
+
+    public Statement apply( final Statement base, final Description description ) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+
+                try {
+                    base.evaluate();
+                }
+                catch ( Throwable t ) {
+
+                    if ( !isMissingCredsException( t ) ) {
+                        throw t;
+                    }
+
+                    //do this so our test gets marked as ignored.  Not pretty, but it works
+                    Assume.assumeTrue( false );
+
+
+                }
+            }
+        };
+    }
+
+
+    private boolean isMissingCredsException( final Throwable t ) {
+
+        if ( t instanceof AmazonClientException ) {
+
+            final AmazonClientException ace = ( AmazonClientException ) t;
+
+            if ( ace.getMessage().contains( "could not get aws access key" ) || ace.getMessage().contains(
+                "could not get aws secret key from system properties" ) ) {
+                //swallow
+                return true;
+            }
+        }
+
+        /**
+         * Handle the multiple failure junit trace
+         */
+        if( t instanceof MultipleFailureException ){
+            for(final Throwable failure : ((MultipleFailureException)t).getFailures()){
+                final boolean isMissingCreds = isMissingCredsException( failure );
+
+                if(isMissingCreds){
+                    return true;
+                }
+            }
+        }
+        final Throwable cause = t.getCause();
+
+        if ( cause == null ) {
+            return false;
+        }
+
+
+        return isMissingCredsException( cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
index bcaa521..cb9a099 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/management/RegistrationIT.java
@@ -43,33 +43,6 @@ public class RegistrationIT extends AbstractRestIT {
 
     private static final Logger logger = LoggerFactory.getLogger(RegistrationIT.class);
 
-    public Map<String, Object> getRemoteTestProperties() {
-        return clientSetup.getRestClient().testPropertiesResource().get().getProperties();
-    }
-
-    /**
-     * Sets a management service property locally and remotely.
-     */
-    public void setTestProperty(String key, Object value) {
-        // set the value remotely (in the Usergrid instance running in Tomcat classloader)
-        Entity props = new Entity();
-        props.put(key, value);
-        clientSetup.getRestClient().testPropertiesResource().post(props);
-
-    }
-
-    public void setTestProperties(Map<String, Object> props) {
-        Entity properties = new Entity();
-        // set the values locally (in the Usergrid instance here in the JUnit classloader
-        for (String key : props.keySet()) {
-            properties.put(key, props.get(key));
-
-        }
-
-        // set the values remotely (in the Usergrid instance running in Tomcat classloader)
-        clientSetup.getRestClient().testPropertiesResource().post(properties);
-    }
-
     public String getTokenFromMessage(Message msg) throws IOException, MessagingException {
         String body = ((MimeMultipart) msg.getContent()).getBodyPart(0).getContent().toString();
         // TODO better token extraction

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/AbstractRestIT.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/AbstractRestIT.java b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/AbstractRestIT.java
index 4ef2069..1d9c23e 100644
--- a/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/AbstractRestIT.java
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/test/resource/AbstractRestIT.java
@@ -32,6 +32,7 @@ import org.apache.usergrid.rest.test.resource.endpoints.ApplicationsResource;
 import org.apache.usergrid.rest.test.resource.endpoints.NamedResource;
 import org.apache.usergrid.rest.test.resource.endpoints.OrganizationResource;
 import org.apache.usergrid.rest.test.resource.endpoints.mgmt.ManagementResource;
+import org.apache.usergrid.rest.test.resource.model.Entity;
 import org.apache.usergrid.rest.test.resource.model.Token;
 import org.apache.usergrid.rest.test.resource.state.ClientContext;
 import org.junit.Rule;
@@ -40,6 +41,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLClassLoader;
 import java.util.Arrays;
+import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
 
@@ -126,7 +128,7 @@ public class AbstractRestIT extends JerseyTest {
 
     //myorg/myapp
     protected ApplicationsResource app(){
-        return clientSetup.restClient.org(clientSetup.getOrganization().getName()).app(clientSetup.getAppName());
+        return clientSetup.restClient.org(clientSetup.getOrganization().getName()).app( clientSetup.getAppName() );
 
     }
 
@@ -134,7 +136,7 @@ public class AbstractRestIT extends JerseyTest {
         return clientSetup.restClient.management();
     }
 
-    protected NamedResource pathResource(String path){ return clientSetup.restClient.pathResource(path);}
+    protected NamedResource pathResource(String path){ return clientSetup.restClient.pathResource( path );}
 
     protected String getOrgAppPath(String additionalPath){
         return clientSetup.orgName + "/" + clientSetup.appName + "/" + (additionalPath !=null ? additionalPath : "");
@@ -146,7 +148,7 @@ public class AbstractRestIT extends JerseyTest {
 
 
     protected Token getAppUserToken(String username, String password){
-        return this.app().token().post(new Token(username,password));
+        return this.app().token().post( new Token( username, password ) );
     }
 
     public void refreshIndex() {
@@ -181,4 +183,32 @@ public class AbstractRestIT extends JerseyTest {
                 new Token(this.clientSetup.getUsername(),this.clientSetup.getUsername()),null,false
         );
     }
+    public Map<String, Object> getRemoteTestProperties() {
+        return clientSetup.getRestClient().testPropertiesResource().get().getProperties();
+    }
+
+    /**
+     * Sets a management service property locally and remotely.
+     */
+    public void setTestProperty(String key, Object value) {
+        // set the value remotely (in the Usergrid instance running in Tomcat classloader)
+        Entity props = new Entity();
+        props.put(key, value);
+        clientSetup.getRestClient().testPropertiesResource().post(props);
+
+    }
+
+    public void setTestProperties(Map<String, Object> props) {
+        Entity properties = new Entity();
+        // set the values locally (in the Usergrid instance here in the JUnit classloader
+        for (String key : props.keySet()) {
+            properties.put(key, props.get(key));
+
+        }
+
+        // set the values remotely (in the Usergrid instance running in Tomcat classloader)
+        clientSetup.getRestClient().testPropertiesResource().post(properties);
+    }
+
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/ca8d1c32/stack/services/src/main/java/org/apache/usergrid/management/AccountCreationProps.java
----------------------------------------------------------------------
diff --git a/stack/services/src/main/java/org/apache/usergrid/management/AccountCreationProps.java b/stack/services/src/main/java/org/apache/usergrid/management/AccountCreationProps.java
index 6c000e2..e7870f7 100644
--- a/stack/services/src/main/java/org/apache/usergrid/management/AccountCreationProps.java
+++ b/stack/services/src/main/java/org/apache/usergrid/management/AccountCreationProps.java
@@ -97,6 +97,8 @@ public interface AccountCreationProps {
     public static final String PROPERTIES_TEST_ACCOUNT_APP = "usergrid.test-account.app";
     public static final String PROPERTIES_SETUP_TEST_ACCOUNT = "usergrid.setup-test-account";
 
+    public static final String PROPERTIES_USERGRID_BINARY_UPLOADER="usergrid.binary.uploader";
+
     public boolean newOrganizationsNeedSysAdminApproval();
 
     public boolean newAdminUsersNeedSysAdminApproval();