Skip to content

Commit

Permalink
Merge pull request #11 from emgerner-msft/master
Browse files Browse the repository at this point in the history
Android Storage Client Library 0.5.1
  • Loading branch information
emgerner-msft committed May 26, 2015
2 parents abf92ec + 4abe59b commit 9339840
Show file tree
Hide file tree
Showing 27 changed files with 525 additions and 225 deletions.
8 changes: 8 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
2015.05.26 Version 0.5.1
* Fixed a bug where maximum execution time was ignored for file, queue, and table services.
* Changed the socket timeout to be set to the service side timeout plus 5 minutes when maximum execution time is not set.
* Changed the socket timeout to default to 5 minutes rather than infinite when neither service side timeout or maximum execution time are set.
* Fixed a bug where MD5 was calculated for commitBlockList even though UseTransactionalMD5 was set to false.
* Fixed a bug where selecting fields that did not exist returned an error rather than an EntityProperty with a null value.
* Fixed a bug where table entities with a single quote in their partition or row key could be inserted but not operated on in any other way.

2015.04.02 Version 0.5.0
* Fixed a bug for all listing API's where next() would sometimes throw an exception if hasNext() had not been called even if there were more elements to iterate on.
* Added sequence number to the blob properties. This is populated for page blobs.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ First, add mavenCentral to your repositories by adding the following to your gra
Then, add a dependency by adding the following to your gradle build file:

dependencies {
compile 'com.microsoft.azure.android:azure-storage-android:0.5.0@aar'
compile 'com.microsoft.azure.android:azure-storage-android:0.5.1@aar'
}

###Option 4: aar via Maven
Expand All @@ -55,7 +55,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w
<dependency>
<groupId>com.microsoft.azure.android</groupId>
<artifactId>azure-storage-android</artifactId>
<version>0.5.0</version>
<version>0.5.1</version>
<type>aar</type>
</dependency>
```
Expand Down
2 changes: 1 addition & 1 deletion microsoft-azure-storage-samples/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.azure.storage.samples"
android:versionCode="0"
android:versionName="0.5.0" >
android:versionName="0.5.1" >

<uses-sdk
android:minSdkVersion="15"
Expand Down
2 changes: 1 addition & 1 deletion microsoft-azure-storage-test/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.azure.android.test"
android:versionCode="0"
android:versionName="0.5.0" >
android:versionName="0.5.1" >

<uses-sdk
android:minSdkVersion="15"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,170 +220,6 @@ public void testNullRetryPolicy() throws URISyntaxException, StorageException {
container.exists();
}

public void testMaximumExecutionTime() throws URISyntaxException, StorageException {
OperationContext opContext = new OperationContext();
setDelay(opContext, 2500);

// set the maximum execution time
BlobRequestOptions options = new BlobRequestOptions();
options.setMaximumExecutionTimeInMs(2000);

// set the location mode to secondary, secondary request should fail
// so set the timeout low to save time failing (or fail with a timeout)
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
options.setTimeoutIntervalInMs(1000);

CloudBlobClient blobClient = TestHelper.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName());

try {
// 1. download attributes will fail as the container does not exist
// 2. the executor will attempt to retry as it is accessing secondary
// 3. maximum execution time should prevent the retry from being made
container.downloadAttributes(null, options, opContext);
fail("Maximum execution time was reached but request did not fail.");
}
catch (StorageException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getMessage());
}
}

public void testMaximumExecutionTimeBlobWrites() throws URISyntaxException, StorageException, IOException {
byte[] buffer = BlobTestHelper.getRandomBuffer(80 * 1024 * 1024);

// set the maximum execution time
BlobRequestOptions options = new BlobRequestOptions();
options.setMaximumExecutionTimeInMs(5000);

CloudBlobClient blobClient = TestHelper.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName());

String blobName = "testBlob";
final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blobName);
blockBlobRef.setStreamWriteSizeInBytes(1 * 1024 * 1024);

ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
BlobOutputStream blobOutputStream = null;

try {
container.createIfNotExists();

// make sure max timeout is thrown by Utility.writeToOutputStream() on upload
try {
blockBlobRef.upload(inputStream, buffer.length, null, options, null);
fail("Maximum execution time was reached but request did not fail.");
}
catch (StorageException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getMessage());
}
catch (IOException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
assertFalse(blockBlobRef.exists());

// make sure max timeout applies on a per service request basis if the user creates the stream
// adds a delay so the first service request should fail
OperationContext opContext = new OperationContext();
setDelay(opContext, 6000);
blobOutputStream = blockBlobRef.openOutputStream(null, options, opContext);
try {
blobOutputStream.write(inputStream, buffer.length);
fail("Maximum execution time was reached but request did not fail.");
}
catch (StorageException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
catch (IOException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
finally {
try {
blobOutputStream.close();
}
catch (IOException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
}
assertFalse(blockBlobRef.exists());

// make sure max timeout applies on a per service request basis if the user creates the stream
// adds a delay so the first service request should fail
blobOutputStream = blockBlobRef.openOutputStream(null, options, opContext);
try {
blobOutputStream.write(buffer);
fail("Maximum execution time was reached but request did not fail.");
}
catch (IOException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
finally {
try {
blobOutputStream.close();
}
catch (IOException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
}
assertFalse(blockBlobRef.exists());

// make sure max timeout applies on a per service request basis only if the user creates the stream
// should succeed as even if all requests would exceed the timeout, each one won't
blobOutputStream = blockBlobRef.openOutputStream(null, options, null);
try {
blobOutputStream.write(inputStream, buffer.length);
}
finally {
blobOutputStream.close();
}
assertTrue(blockBlobRef.exists());
}
finally {
inputStream.close();
container.deleteIfExists();
}
}

public void testMaximumExecutionTimeBlobByteArray() throws URISyntaxException, StorageException, IOException {
int length = 10 * 1024 * 1024;
byte[] uploadBuffer = BlobTestHelper.getRandomBuffer(length);
byte[] downloadBuffer = new byte[length];

// set a delay in sending request
OperationContext opContext = new OperationContext();
setDelay(opContext, 2500);

// set the maximum execution time
BlobRequestOptions options = new BlobRequestOptions();
options.setMaximumExecutionTimeInMs(2000);

CloudBlobClient blobClient = TestHelper.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName());

String blobName = "testBlob";
final CloudBlockBlob blockBlobRef = container.getBlockBlobReference(blobName);

ByteArrayInputStream inputStream = new ByteArrayInputStream(uploadBuffer);

try {
container.createIfNotExists();

blockBlobRef.upload(inputStream, length);
assertTrue(blockBlobRef.exists());

try {
blockBlobRef.downloadToByteArray(downloadBuffer, 0, null, options, opContext);
fail("Maximum execution time was reached but request did not fail.");
}
catch (StorageException e) {
assertEquals(SR.MAXIMUM_EXECUTION_TIMEOUT_EXCEPTION, e.getCause().getMessage());
}
}
finally {
inputStream.close();
container.deleteIfExists();
}
}

public void testDateStringParsingWithRounding() throws ParseException {
String fullDateString = "1999-12-31T23:59:45.1234567Z";
SimpleDateFormat testFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
Expand Down Expand Up @@ -504,20 +340,4 @@ private static String generateRandomContainerName() {
String containerName = "container" + UUID.randomUUID().toString();
return containerName.replace("-", "");
}

private void setDelay(final OperationContext ctx, final int timeInMs) {

ctx.getSendingRequestEventHandler().addListener(new StorageEvent<SendingRequestEvent>() {

@Override
public void eventOccurred(SendingRequestEvent eventArg) {
try {
Thread.sleep(timeInMs);
}
catch (InterruptedException e) {
// do nothing
}
}
});
}
}
Loading

0 comments on commit 9339840

Please sign in to comment.