Merge branch 'sso-conn-pool' into USERGRID-579-jcloud171
diff --git a/stack/pom.xml b/stack/pom.xml
index 4f50779..5c3d4fe 100644
--- a/stack/pom.xml
+++ b/stack/pom.xml
@@ -95,7 +95,7 @@
<hector-version>1.1-4</hector-version>
<hector-test-version>1.1-4</hector-test-version>
<jackson-version>1.9.9</jackson-version>
- <jclouds.version>1.6.2-incubating</jclouds.version>
+ <jclouds.version>1.7.1</jclouds.version>
<jersey-version>1.18</jersey-version>
<junit-version>4.11</junit-version>
<log4j-version>1.2.16</log4j-version>
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 d5ef311..3eee96b 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
@@ -595,7 +595,7 @@
ServiceResults serviceResults = executeServiceRequest( ui, response, ServiceAction.GET, null );
Entity entity = serviceResults.getEntity();
- LOG.info( "In AssetsResource.findAsset with id: {}, range: {}, modifiedSince: {}",
+ LOG.info( "In ServiceResource.executeStreamGet with id: {}, range: {}, modifiedSince: {}",
new Object[] { entityId, rangeHeader, modifiedSince } );
Map<String, Object> fileMetadata = AssetUtils.getFileMetadata( entity );
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 b41659d..666f95e 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
@@ -139,10 +139,14 @@
UserRepo.INSTANCE.load( resource(), access_token );
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 = resource().path( "/test-organization/test-app/foos" ).queryParam( "access_token", access_token )
- .accept( MediaType.APPLICATION_JSON ).type( MediaType.MULTIPART_FORM_DATA )
+ FormDataMultiPart form = new FormDataMultiPart()
+ .field( "file", data, MediaType.MULTIPART_FORM_DATA_TYPE );
+
+ 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 idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
@@ -151,25 +155,47 @@
logNode( node );
// get entity
- node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
- .accept( MediaType.APPLICATION_JSON_TYPE ).get( JsonNode.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( "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.getTextValue() );
- // 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];
- byte[] foundData = IOUtils.toByteArray( is );
+ // retry until upload complete
+ while ( !done && retries < 30 ) {
+
+ // get data
+ try {
+ InputStream is = resource().path( "/test-organization/test-app/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++;
+ }
+
assertEquals( 5324800, foundData.length );
// delete
- node = resource().path( "/test-organization/test-app/foos/" + uuid ).queryParam( "access_token", access_token )
- .accept( MediaType.APPLICATION_JSON_TYPE ).delete( JsonNode.class );
+ node = resource().path( "/test-organization/test-app/foos/" + uuid )
+ .queryParam( "access_token", access_token )
+ .accept( MediaType.APPLICATION_JSON_TYPE )
+ .delete( JsonNode.class );
}
diff --git a/stack/services/src/main/java/org/apache/usergrid/services/assets/data/S3BinaryStore.java b/stack/services/src/main/java/org/apache/usergrid/services/assets/data/S3BinaryStore.java
index e1748d3..29b5e47 100644
--- a/stack/services/src/main/java/org/apache/usergrid/services/assets/data/S3BinaryStore.java
+++ b/stack/services/src/main/java/org/apache/usergrid/services/assets/data/S3BinaryStore.java
@@ -104,7 +104,7 @@
@Override
public void write( final UUID appId, final Entity entity, InputStream inputStream ) throws IOException {
- String uploadFileName = AssetUtils.buildAssetKey( appId, entity );
+ final String uploadFileName = AssetUtils.buildAssetKey( appId, entity );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
long written = IOUtils.copyLarge( inputStream, baos, 0, FIVE_MB );
byte[] data = baos.toByteArray();
@@ -112,13 +112,13 @@
final Map<String, Object> fileMetadata = AssetUtils.getFileMetadata( entity );
fileMetadata.put( AssetUtils.LAST_MODIFIED, System.currentTimeMillis() );
- String mimeType = AssetMimeHandler.get().getMimeType( entity, data );
+ final String mimeType = AssetMimeHandler.get().getMimeType( entity, data );
if ( written < FIVE_MB ) { // total smaller than 5mb
BlobStore blobStore = getContext().getBlobStore();
- BlobBuilder.PayloadBlobBuilder bb =
- blobStore.blobBuilder( uploadFileName ).payload( data ).calculateMD5().contentType( mimeType );
+ BlobBuilder.PayloadBlobBuilder bb = blobStore.blobBuilder( uploadFileName )
+ .payload( data ).calculateMD5().contentType( mimeType );
fileMetadata.put( AssetUtils.CONTENT_LENGTH, written );
if ( fileMetadata.get( AssetUtils.CONTENT_DISPOSITION ) != null ) {
@@ -134,10 +134,11 @@
}
else { // bigger than 5mb... dump 5 mb tmp files and upload from them
- // todo: yes, AsyncBlobStore is deprecated, but there appears to be no replacement yet
- final AsyncBlobStore blobStore = getContext().getAsyncBlobStore();
+ // create temp file and copy entire file to that temp file
- File tempFile = File.createTempFile( entity.getUuid().toString(), "tmp" );
+ LOG.debug( "Writing temp file for S3 upload" );
+
+ final File tempFile = File.createTempFile( entity.getUuid().toString(), "tmp" );
tempFile.deleteOnExit();
OutputStream os = null;
try {
@@ -149,38 +150,52 @@
IOUtils.closeQuietly( os );
}
- BlobBuilder.PayloadBlobBuilder bb =
- blobStore.blobBuilder( uploadFileName ).payload( tempFile ).calculateMD5().contentType( mimeType );
-
fileMetadata.put( AssetUtils.CONTENT_LENGTH, written );
- if ( fileMetadata.get( AssetUtils.CONTENT_DISPOSITION ) != null ) {
- bb.contentDisposition( fileMetadata.get( AssetUtils.CONTENT_DISPOSITION ).toString() );
- }
- final Blob blob = bb.build();
- final File finalTempFile = tempFile;
- final ListenableFuture<String> future =
- blobStore.putBlob( bucketName, blob, PutOptions.Builder.multipart() );
+ // JClouds no longer supports async blob store, so we have to do this fun stuff
- Runnable listener = new Runnable() {
+ LOG.debug( "Starting upload thread" );
+
+ Thread uploadThread = new Thread( new Runnable() {
@Override
public void run() {
try {
- String eTag = future.get();
+ LOG.debug( "S3 upload thread started" );
+
+ BlobStore blobStore = getContext().getBlobStore();
+
+ BlobBuilder.PayloadBlobBuilder bb = blobStore.blobBuilder( uploadFileName )
+ .payload( tempFile ).calculateMD5().contentType( mimeType );
+
+ if ( fileMetadata.get( AssetUtils.CONTENT_DISPOSITION ) != null ) {
+ bb.contentDisposition( fileMetadata.get( AssetUtils.CONTENT_DISPOSITION ).toString() );
+ }
+ final Blob blob = bb.build();
+
+ String md5sum = Hex.encodeHexString( blob.getMetadata().getContentMetadata().getContentMD5() );
+ fileMetadata.put( AssetUtils.CHECKSUM, md5sum );
+
+ LOG.debug( "S3 upload starting" );
+
+ String eTag = blobStore.putBlob( bucketName, blob );
fileMetadata.put( AssetUtils.E_TAG, eTag );
+
+ LOG.debug( "S3 upload complete eTag=" + eTag);
+
EntityManager em = emf.getEntityManager( appId );
em.update( entity );
- finalTempFile.delete();
+ tempFile.delete();
}
catch ( Exception e ) {
LOG.error( "error uploading", e );
}
- if ( finalTempFile != null && finalTempFile.exists() ) {
- finalTempFile.delete();
+ if ( tempFile != null && tempFile.exists() ) {
+ tempFile.delete();
}
}
- };
- future.addListener( listener, executor );
+ });
+
+ uploadThread.start();
}
}