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

Commit eb29cfe

Browse files
authored
Merge 7.0 Release
7.0 Release
2 parents 9a16e35 + 3cf48a3 commit eb29cfe

File tree

91 files changed

+1564
-465
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+1564
-465
lines changed

BreakingChanges.txt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
Changes in 6.0.0
1+
Changes in 7.0.0
2+
3+
OTHER
4+
* Upgraded Key Vault dependency to 1.0. Users of the IKey and IKeyResolver interfaces should note the interface changes in this version.
5+
* The getErrorCode method of StorageExtendedErrorInformation is now deprecated. Use the corresponding methods in RequestResult and StorageException instead.
6+
7+
Changes in 6.0.0
28

39
FILE
4-
* Many File service APIs can now throw a URISyntaxException.
5-
* Changed listShares() ShareListingDetails parameter to be an enum set like what is done for listing blobs.
10+
* Many File service APIs can now throw a URISyntaxException.
11+
* Changed listShares() ShareListingDetails parameter to be an enum set like what is done for listing blobs.
612

713
OTHER
814
* DefaultEndpointsProtocol will now be explicitly included in generated connection strings.
915
* Connection string parsing has been substantially re-written and expanded. Please refer to current documentation about connection string formats.
1016

1117
Changes in 5.1.1
1218
OTHER
13-
* Reverted the code from 5.1.0 because it contained a regression and an accidental change.
19+
* Reverted the code from 5.1.0 because it contained a regression and an accidental change.
1420

1521
Changes in 5.0.0
1622

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The Azure Storage development team uses Intellij. However, any preferred IDE or
2020

2121
### Configuration
2222
The only step to configure testing is to setup a configuration file or connection string via environment variables. To use the connection string route, create an environment variable named "storageConnection". To use the configuration file route, create an environment variable named "storageTestConfiguration" with the path to a TestConfigurations.xml file with this [template](https://github.com/Azure/azure-storage-java/blob/master/microsoft-azure-storage-test/res/TestConfigurations.xml).
23+
Alternatively, you can fill in microsoft-azure-storage-test/res/TestConfigurations.xml with the appropriate information.
2324

2425
### Running
2526
To actually run tests, right click on the test class in the Package Explorer or the individual test in the Outline and select Run As->JUnitTest. All tests or tests grouped by service can be run using the test runners in the com.microsoft.azure.storage package TestRunners file. Running all tests from the top of the package explorer will result in each test being run multiple times as the package explorer will also run every test runner.

ChangeLog.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2018.02.05 Version 7.0.0
2+
* Support for 2017-07-29 REST version. Please see our REST api documentation and blogs for information about the related added features.
3+
* Added support for soft delete feature. If a delete retention policy is enabled through the set service properties API, then blobs or snapshots can be deleted softly and retained for a specified number of days, before being permanently removed by garbage collection.
4+
* When a storage request fails, the error code may now be retrieved directly from the RequestResult and StorageException classes. This error code is populated even in cases where there is no StorageExtendedErrorInformation available, such as in calls to FetchAttributes.
5+
* Queue messages may now be inserted with infinite duration by specifying -1 as the timeToLiveInSeconds parameter to addMessage.
6+
* Improved performance of blob uploadFromFile APIs to avoid unnecessary buffering.
7+
* Improved performance when streaming directly from a FileInputStream to avoid unnecessary buffering.
8+
* Switched to using fixed length streaming mode in the HTTP client to avoid unnecessary buffering.
9+
* Upgraded Key Vault dependency to 1.0.
10+
* Fixed a bug preventing openInputStream from working on a blob snapshot.
11+
112
2017.11.01 Version 6.1.0
213
* Added support for the last time the tier was modified.
314

microsoft-azure-storage-test/src/com/microsoft/azure/storage/AlwaysRetry.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import java.util.ArrayList;
1818
import java.util.List;
1919

20-
import static junit.framework.Assert.assertEquals;
21-
import static junit.framework.Assert.assertTrue;
20+
import static org.junit.Assert.assertEquals;
21+
import static org.junit.Assert.assertTrue;
2222

2323
public class AlwaysRetry extends RetryPolicy implements RetryPolicyFactory {
2424

microsoft-azure-storage-test/src/com/microsoft/azure/storage/DictionaryKeyResolver.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
import java.util.HashMap;
1818
import java.util.Map;
19-
import java.util.concurrent.Future;
2019

21-
import org.apache.commons.lang3.concurrent.ConcurrentUtils;
20+
import com.google.common.util.concurrent.ListenableFuture;
21+
import com.google.common.util.concurrent.SettableFuture;
2222

2323
import com.microsoft.azure.keyvault.core.IKey;
2424
import com.microsoft.azure.keyvault.core.IKeyResolver;
@@ -32,8 +32,10 @@ public void add(IKey key)
3232
}
3333

3434
@Override
35-
public Future<IKey> resolveKeyAsync(String keyId)
35+
public ListenableFuture<IKey> resolveKeyAsync(String keyId)
3636
{
37-
return ConcurrentUtils.constantFuture(this.keys.get(keyId));
37+
SettableFuture<IKey> future = SettableFuture.create();
38+
future.set(this.keys.get(keyId));
39+
return future;
3840
}
3941
}

microsoft-azure-storage-test/src/com/microsoft/azure/storage/EventFiringTests.java

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,6 @@ public void testErrorReceivingResponseEvent() throws URISyntaxException, Storage
168168
BlobRequestOptions options = new BlobRequestOptions();
169169
options.setRetryPolicyFactory(new RetryNoRetry());
170170

171-
// setting the sending request event handler to trigger an exception.
172-
// this is a retryable exception
173-
eventContext.getSendingRequestEventHandler().addListener(new StorageEvent<SendingRequestEvent>() {
174-
@Override
175-
public void eventOccurred(SendingRequestEvent eventArg) {
176-
HttpURLConnection connection = (HttpURLConnection) eventArg.getConnectionObject();
177-
connection.setFixedLengthStreamingMode(0);
178-
}
179-
});
180-
181171
eventContext.getErrorReceivingResponseEventHandler().addListener(new StorageEvent<ErrorReceivingResponseEvent>() {
182172
@Override
183173
public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
@@ -186,13 +176,15 @@ public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
186176
}
187177
});
188178

189-
OperationContext.getGlobalErrorReceivingResponseEventHandler().addListener(new StorageEvent<ErrorReceivingResponseEvent>() {
179+
StorageEvent<ErrorReceivingResponseEvent> globalEvent = new StorageEvent<ErrorReceivingResponseEvent>() {
190180
@Override
191181
public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
192182
assertEquals(eventArg.getRequestResult(), eventArg.getOpContext().getLastResult());
193183
globalCallList.add(true);
194184
}
195-
});
185+
};
186+
187+
OperationContext.getGlobalErrorReceivingResponseEventHandler().addListener(globalEvent);
196188

197189
CloudBlobClient blobClient = TestHelper.createCloudBlobClient();
198190
CloudBlobContainer container = blobClient.getContainerReference("container1");
@@ -202,10 +194,12 @@ public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
202194
CloudBlockBlob blob1 = container.getBlockBlobReference("blob1");
203195
try {
204196
String blockID = String.format("%08d", 1);
205-
blob1.uploadBlock(blockID, BlobTestHelper.getRandomDataStream(10), 10, null, options, eventContext);
197+
198+
// Trigger an error receiving the response by sending more bytes than the stream has.
199+
blob1.uploadBlock(blockID, BlobTestHelper.getRandomDataStream(10), 11, null, options, eventContext);
206200
} catch (Exception e) { }
207201

208-
// make sure both the local and globab context update
202+
// make sure both the local and global context update
209203
assertEquals(1, callList.size());
210204
assertEquals(1, globalCallList.size());
211205

@@ -214,7 +208,9 @@ public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
214208
.setErrorReceivingResponseEventHandler(new StorageEventMultiCaster<ErrorReceivingResponseEvent, StorageEvent<ErrorReceivingResponseEvent>>());
215209
try {
216210
String blockID2 = String.format("%08d", 2);
217-
blob1.uploadBlock(blockID2, BlobTestHelper.getRandomDataStream(10), 10, null, options, eventContext);
211+
212+
// Trigger an error receiving the response by sending more bytes than the stream has.
213+
blob1.uploadBlock(blockID2, BlobTestHelper.getRandomDataStream(10), 11, null, options, eventContext);
218214
} catch (Exception e) { }
219215

220216
assertEquals(1, callList.size());
@@ -227,13 +223,17 @@ public void eventOccurred(ErrorReceivingResponseEvent eventArg) {
227223
// make sure neither update
228224
try {
229225
String blockID3 = String.format("%08d", 3);
230-
blob1.uploadBlock(blockID3, BlobTestHelper.getRandomDataStream(10), 10, null, options, eventContext);
226+
227+
// Trigger an error receiving the response by sending more bytes than the stream has.
228+
blob1.uploadBlock(blockID3, BlobTestHelper.getRandomDataStream(10), 11, null, options, eventContext);
231229
} catch (Exception e) { }
232230

233231
assertEquals(1, callList.size());
234232
assertEquals(2, globalCallList.size());
235233
}
236234
finally {
235+
// Remove the global listener if it wasn't removed already.
236+
OperationContext.getGlobalErrorReceivingResponseEventHandler().removeListener(globalEvent);
237237
container.deleteIfExists();
238238
}
239239
}
@@ -338,7 +338,7 @@ public void eventOccurred(RetryingEvent eventArg) {
338338
catch (StorageException e) {
339339
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, e.getHttpStatusCode());
340340
assertEquals("The specified container does not exist.", e.getMessage());
341-
assertEquals(StorageErrorCode.RESOURCE_NOT_FOUND.toString(), e.getErrorCode());
341+
assertEquals(StorageErrorCodeStrings.CONTAINER_NOT_FOUND, e.getErrorCode());
342342
}
343343
assertEquals(1, callList.size());
344344
assertEquals(1, globalCallList.size());
@@ -351,7 +351,7 @@ public void eventOccurred(RetryingEvent eventArg) {
351351
catch (StorageException e) {
352352
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, e.getHttpStatusCode());
353353
assertEquals("The specified container does not exist.", e.getMessage());
354-
assertEquals(StorageErrorCode.RESOURCE_NOT_FOUND.toString(), e.getErrorCode());
354+
assertEquals(StorageErrorCodeStrings.CONTAINER_NOT_FOUND, e.getErrorCode());
355355
}
356356
assertEquals(1, callList.size());
357357
assertEquals(2, globalCallList.size());
@@ -368,7 +368,7 @@ public void eventOccurred(RetryingEvent eventArg) {
368368
catch (StorageException e) {
369369
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, e.getHttpStatusCode());
370370
assertEquals("The specified container does not exist.", e.getMessage());
371-
assertEquals(StorageErrorCode.RESOURCE_NOT_FOUND.toString(), e.getErrorCode());
371+
assertEquals(StorageErrorCodeStrings.CONTAINER_NOT_FOUND, e.getErrorCode());
372372
}
373373
assertEquals(1, callList.size());
374374
assertEquals(2, globalCallList.size());
@@ -422,7 +422,7 @@ public void eventOccurred(RequestCompletedEvent eventArg) {
422422
catch (StorageException e) {
423423
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, e.getHttpStatusCode());
424424
assertEquals("The specified container does not exist.", e.getMessage());
425-
assertEquals(StorageErrorCode.RESOURCE_NOT_FOUND.toString(), e.getErrorCode());
425+
assertEquals(StorageErrorCodeStrings.CONTAINER_NOT_FOUND, e.getErrorCode());
426426
}
427427

428428
assertEquals(2, sendingCallList.size());

microsoft-azure-storage-test/src/com/microsoft/azure/storage/GenericTests.java

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,8 @@
1414
*/
1515
package com.microsoft.azure.storage;
1616

17-
import com.microsoft.azure.storage.blob.BlobOutputStream;
18-
import com.microsoft.azure.storage.blob.BlobRequestOptions;
19-
import com.microsoft.azure.storage.blob.BlobTestHelper;
20-
import com.microsoft.azure.storage.blob.CloudBlobClient;
21-
import com.microsoft.azure.storage.blob.CloudBlobContainer;
22-
import com.microsoft.azure.storage.blob.CloudBlockBlob;
17+
import com.microsoft.azure.storage.blob.*;
18+
import com.microsoft.azure.storage.core.BaseRequest;
2319
import com.microsoft.azure.storage.core.SR;
2420
import com.microsoft.azure.storage.core.Utility;
2521
import com.microsoft.azure.storage.queue.CloudQueue;
@@ -476,4 +472,45 @@ private static String generateRandomContainerName() {
476472
String containerName = "container" + UUID.randomUUID().toString();
477473
return containerName.replace("-", "");
478474
}
475+
476+
@Test
477+
public void testErrorCodeFromHeader() throws URISyntaxException, StorageException, IOException {
478+
CloudBlobClient blobClient = TestHelper.createCloudBlobClient();
479+
CloudBlobContainer container = blobClient.getContainerReference(generateRandomContainerName());
480+
481+
CloudAppendBlob appendBlob = container.getAppendBlobReference("testAppend");
482+
483+
try {
484+
container.createIfNotExists();
485+
OperationContext ctx = new OperationContext();
486+
appendBlob.createOrReplace();
487+
488+
// Verify that the error code is set on a non HEAD request
489+
try {
490+
appendBlob.delete(DeleteSnapshotsOption.NONE, AccessCondition.generateIfMatchCondition("garbage"),
491+
null, ctx);
492+
}
493+
catch (Exception e) {
494+
// Validate that the error code is set on the exception and the result
495+
assertEquals(((StorageException)e).getErrorCode(), StorageErrorCodeStrings.CONDITION_NOT_MET);
496+
assertEquals(ctx.getLastResult().getErrorCode(), StorageErrorCodeStrings.CONDITION_NOT_MET);
497+
}
498+
499+
// Verify that the error code is set on a HEAD request
500+
try {
501+
appendBlob.downloadAttributes(AccessCondition.generateIfMatchCondition("garbage"), null, ctx);
502+
}
503+
catch (Exception e) {
504+
assertEquals(((StorageException)e).getErrorCode(), StorageErrorCodeStrings.CONDITION_NOT_MET);
505+
assertEquals(ctx.getLastResult().getErrorCode(), StorageErrorCodeStrings.CONDITION_NOT_MET);
506+
}
507+
508+
// Verify that the ErrorCode is not set on a successful request
509+
appendBlob.delete(DeleteSnapshotsOption.NONE, null, null, ctx);
510+
assertEquals(ctx.getLastResult().getErrorCode(), null);
511+
}
512+
finally {
513+
container.deleteIfExists();
514+
}
515+
}
479516
}

0 commit comments

Comments
 (0)