Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Commit

Permalink
Java Storage Client Library 2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
emgerner-msft committed May 26, 2015
1 parent 950761b commit 16072ef
Show file tree
Hide file tree
Showing 25 changed files with 563 additions and 230 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 2.2.0
* 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.01 Version 2.1.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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion microsoft-azure-storage-samples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.CloudBlobContainer;
import com.microsoft.azure.storage.blob.CloudBlockBlob;
import com.microsoft.azure.storage.core.BaseRequest;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.core.Utility;
import com.microsoft.azure.storage.queue.CloudQueue;
Expand Down Expand Up @@ -247,176 +246,6 @@ public void testNullRetryPolicy() throws URISyntaxException, StorageException {
container.exists();
}

@Test
@Category({ DevFabricTests.class, DevStoreTests.class, SecondaryTests.class })
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());
}
}

@Test
@Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class })
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();
}
}

@Test
@Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class })
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();
}
}

@Test
public void testDateStringParsingWithRounding() throws ParseException {
String fullDateString = "1999-12-31T23:59:45.1234567Z";
Expand Down Expand Up @@ -543,20 +372,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 16072ef

Please sign in to comment.