blob: 666f95e1a900e376f414c7d4dfd89e085791f5a0 [file] [log] [blame]
/*
* 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.Map;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
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.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.apache.usergrid.utils.MapUtils.hashMap;
@Concurrent()
public class AssetResourceIT extends AbstractRestIT {
private Logger LOG = LoggerFactory.getLogger( AssetResourceIT.class );
/** @Deprecated Tests legacy API */
@Test
public void verifyBinaryCrud() throws Exception {
UserRepo.INSTANCE.load( resource(), access_token );
UUID userId = UserRepo.INSTANCE.getByUserName( "user1" );
Map<String, String> payload =
hashMap( "path", "my/clean/path" ).map( "owner", userId.toString() ).map( "someprop", "somevalue" );
JsonNode node =
resource().path( "/test-organization/test-app/assets" ).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 id = UUID.fromString( idNode.getTextValue() );
assertNotNull( idNode.getTextValue() );
logNode( node );
byte[] data = IOUtils.toByteArray( this.getClass().getResourceAsStream( "/cassandra_eye.jpg" ) );
resource().path( "/test-organization/test-app/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" )
.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 );
idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
assertEquals( id.toString(), idNode.getTextValue() );
}
@Test
public void octetStreamOnDynamicEntity() throws Exception {
UserRepo.INSTANCE.load( resource(), access_token );
Map<String, String> payload = hashMap( "name", "assetname" );
JsonNode node = resource().path( "/test-organization/test-app/foos" ).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" );
String uuid = idNode.getTextValue();
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 )
.type( MediaType.APPLICATION_OCTET_STREAM_TYPE ).put( data );
// get entity
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() );
idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
assertEquals( uuid, idNode.getTextValue() );
// get data by UUID
InputStream is =
resource().path( "/test-organization/test-app/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 );
// get data by name
is = resource().path( "/test-organization/test-app/foos/assetname" ).queryParam( "access_token", access_token )
.accept( MediaType.APPLICATION_OCTET_STREAM_TYPE ).get( InputStream.class );
foundData = IOUtils.toByteArray( is );
assertEquals( 7979, foundData.length );
}
@Test
public void multipartPostFormOnDynamicEntity() throws Exception {
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 )
.post( JsonNode.class, form );
JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
String uuid = idNode.getTextValue();
assertNotNull( uuid );
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 );
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() );
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 )
.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 );
}
@Test
public void multipartPutFormOnDynamicEntity() throws Exception {
UserRepo.INSTANCE.load( resource(), access_token );
Map<String, String> payload = hashMap( "foo", "bar" );
JsonNode node = resource().path( "/test-organization/test-app/foos" ).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" );
String uuid = idNode.getTextValue();
assertNotNull( uuid );
logNode( node );
// set file & assetname
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 );
long created = System.currentTimeMillis();
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 );
// get entity
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() );
idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
assertEquals( uuid, idNode.getTextValue() );
JsonNode nameNode = node.get( "entities" ).get( 0 ).get( "foo" );
assertEquals( "bar2", nameNode.getTextValue() );
long lastModified = node.findValue( AssetUtils.LAST_MODIFIED ).getLongValue();
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 );
byte[] foundData = IOUtils.toByteArray( is );
assertEquals( 7979, foundData.length );
// post new data
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 );
Assert.assertTrue( lastModified != node.findValue( AssetUtils.LAST_MODIFIED ).getLongValue() );
}
@Test
@Ignore("Just enable and run when testing S3 large file upload specifically")
public void largeFileInS3() throws Exception {
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 );
// send data
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 );
logNode( node );
JsonNode idNode = node.get( "entities" ).get( 0 ).get( "uuid" );
String uuid = idNode.getTextValue();
// get entity
long timeout = System.currentTimeMillis() + 60000;
while ( true ) {
LOG.info( "Waiting for upload to finish..." );
Thread.sleep( 2000 );
node = resource().path( "/test-organization/test-app/foos/" + uuid )
.queryParam( "access_token", access_token ).accept( MediaType.APPLICATION_JSON_TYPE )
.get( JsonNode.class );
logNode( node );
// poll for the upload to complete
if ( node.findValue( AssetUtils.E_TAG ) != null ) {
break;
}
if ( System.currentTimeMillis() > timeout ) {
throw new TimeoutException();
}
}
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 );
byte[] foundData = IOUtils.toByteArray( is );
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 );
}
/**
* Deleting a connection to an asset should not delete the asset or the asset's data
*/
@Test
public void deleteConnectionToAsset() throws IOException {
UserRepo.INSTANCE.load( resource(), access_token );
final String uuid;
// 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")
.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();
// 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)
.queryParam("access_token", access_token)
.type(MediaType.APPLICATION_OCTET_STREAM_TYPE)
.put(data);
// create an imagegallery entity
Map<String, String> imageGalleryPayload = hashMap("name", "my image gallery");
JsonNode imageGalleryNode = resource().path("/test-organization/test-app/imagegalleries")
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON_TYPE)
.post(JsonNode.class, imageGalleryPayload);
JsonNode imageGalleryIdNode = imageGalleryNode.get("entities").get(0).get("uuid");
String imageGalleryId = imageGalleryIdNode.getTextValue();
// connect imagegallery to asset
JsonNode connectNode = resource()
.path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON_TYPE)
.post(JsonNode.class);
// verify connection from imagegallery to asset
JsonNode listConnectionsNode = resource()
.path("/test-organization/test-app/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());
// delete the connection
resource().path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/" + uuid)
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON_TYPE)
.delete();
// verify that connection is gone
listConnectionsNode = resource()
.path("/test-organization/test-app/imagegalleries/" + imageGalleryId + "/contains/")
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON_TYPE)
.get(JsonNode.class);
assertFalse(listConnectionsNode.get("entities").getElements().hasNext());
// asset should still be there
JsonNode assetNode = resource().path("/test-organization/test-app/foos/" + uuid)
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_JSON_TYPE)
.get(JsonNode.class);
logNode(assetNode);
Assert.assertEquals("image/jpeg", assetNode.findValue(AssetUtils.CONTENT_TYPE).getTextValue());
Assert.assertEquals(7979, assetNode.findValue("content-length").getIntValue());
JsonNode assetIdNode = assetNode.get("entities").get(0).get("uuid");
assertEquals(uuid, assetIdNode.getTextValue());
// asset data should still be there
InputStream assetIs = resource().path("/test-organization/test-app/foos/" + uuid)
.queryParam("access_token", access_token)
.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE)
.get(InputStream.class);
byte[] foundData = IOUtils.toByteArray(assetIs);
assertEquals(7979, foundData.length);
}
}