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

Commit d8ba06b

Browse files
author
jofriedm-msft
authored
Merge pull request #52 from wastore/dev
Dev
2 parents a9f63e9 + 3e48db9 commit d8ba06b

35 files changed

+1456
-225
lines changed

BreakingChanges.txt

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
1+
Changes in 5.1.0
2+
3+
FILE
4+
* Exists() calls on Shares and Directories now populates metadata. This was already being done for Files.
5+
* Changed listShares() ShareListingDetails parameter to be an enum set like what is done for listing blobs.
6+
* In CloudFileShareProperties, setShareQuota() no longer asserts in bounds. This check has been moved to create() and uploadProperties() in CloudFileShare.
7+
8+
BLOB/FILE
9+
* Fixed a bug which prevented setting content MD5 to true when calling openWriteExisting() on a page blob or file.
10+
111
Changes in 5.0.0
212

313
BLOB
414
* getQualifiedUri() has been deprecated. Please use getSnapshotQualifiedUri() instead. This new function will return the blob including the snapshot (if present) and no SAS token.
515
* getQualifiedStorageUri() has been deprecated. Please use getSnapshotQualifiedStorageUri() instead. This new function will return the blob including the snapshot (if present) and no SAS token.
616
* Fixed a bug where copying from a blob that included a SAS token and a snapshot did not use the SAS token.
717

8-
FILE
18+
FILE
919
* Fixed a bug where copying from a blob that included a SAS token and a snapshot did not use the SAS token.
10-
20+
1121
QUEUE
1222
* For addMessage() the CloudQueueMessage message passed in will be populated with the pop receipt, insertion/expiration time, and message ID.
1323

@@ -164,8 +174,8 @@ Changes in 0.5.0
164174

165175
OTHER
166176
* The packaging structure has changed to
167-
1. com.microsoft.windowsazure.storage � RetryPolicies, LocationMode, StorageException, Storage Credentials etc. Basically all public classes that are common across services.
168-
2. com.microsoft.windowsazure.storage.core � These classes are reserved for internal use and users never have to include this namespace in their projects.
177+
1. com.microsoft.windowsazure.storage � RetryPolicies, LocationMode, StorageException, Storage Credentials etc. Basically all public classes that are common across services.
178+
2. com.microsoft.windowsazure.storage.core � These classes are reserved for internal use and users never have to include this namespace in their projects.
169179
3. com.microsoft.windowsazure.storage.blob
170180
4. com.microsoft.windowsazure.storage.queue
171181
5. com.microsoft.windowsazure.storage.table

ChangeLog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
2017.05.04 Version 5.1.0
2+
* Fixed Exists() calls on Shares and Directories to now populate metadata. This was already being done for Files.
3+
* Changed blob constants to support up to 256 MB on put blob for block blobs. The default value for put blob threshold has also been updated to half of the maximum, or 128 MB currently.
4+
* Fixed a bug that prevented setting content MD5 to true when creating a new file.
5+
* Fixed a bug where access conditions, options, and operation context were not being passed when calling openWriteExisting() on a page blob or a file.
6+
* Fixed a bug where an exception was being thrown on a range get of a blob or file when the options disableContentMD5Validation is set to false and useTransactionalContentMD5 is set to true and there is no overall MD5.
7+
* Fixed a bug where retries were happening immediately if a sock exception was thrown.
8+
19
2017.01.18 Version 5.0.0
210
* Prefix support for listing files and directories.
311
* Added support for setting public access when creating a blob container

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ To get the binaries of this library as distributed by Microsoft, ready for use w
3030
<dependency>
3131
<groupId>com.microsoft.azure</groupId>
3232
<artifactId>azure-storage</artifactId>
33-
<version>5.0.0</version>
33+
<version>5.1.0</version>
3434
</dependency>
3535
```
3636

microsoft-azure-storage-samples/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<dependency>
2727
<groupId>com.microsoft.azure</groupId>
2828
<artifactId>azure-storage</artifactId>
29-
<version>5.0.0</version>
29+
<version>5.1.0</version>
3030
</dependency>
3131
<dependency>
3232
<groupId>com.microsoft.azure</groupId>

microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobClientEncryptionTests.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.io.FileOutputStream;
2424
import java.io.IOException;
2525
import java.net.URISyntaxException;
26+
import java.nio.charset.Charset;
2627
import java.security.InvalidAlgorithmParameterException;
2728
import java.security.InvalidKeyException;
2829
import java.security.NoSuchAlgorithmException;
@@ -143,7 +144,41 @@ else if (type == BlobType.APPEND_BLOB) {
143144
TestHelper.assertStreamsAreEqualAtIndex(stream, new ByteArrayInputStream(outputStream.toByteArray()), 0, 0,
144145
size, 2 * 1024);
145146
}
146-
147+
148+
@Test
149+
public void testDownloadUnencryptedBlobWithEncryptionPolicy() throws StorageException, IOException, URISyntaxException, NoSuchAlgorithmException
150+
{
151+
String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("test");
152+
CloudBlockBlob blob = container.getBlockBlobReference(blobName);
153+
blob.deleteIfExists();
154+
155+
byte[] msg = "my message".getBytes();
156+
// Upload data without encryption
157+
blob.uploadFromByteArray(msg, 0, msg.length);
158+
159+
// Create options with encryption policy
160+
BlobRequestOptions options = new BlobRequestOptions();
161+
options.setEncryptionPolicy(new BlobEncryptionPolicy(new RsaKey("myKey", 1024), null));
162+
options.setRequireEncryption(true);
163+
164+
try {
165+
blob.downloadText(Charset.defaultCharset().name(), null, options, null);
166+
fail("Expect exception");
167+
}
168+
catch (StorageException e) {
169+
assertEquals(SR.ENCRYPTION_DATA_NOT_PRESENT_ERROR, e.getMessage());
170+
}
171+
172+
byte[] buffer = new byte[msg.length];
173+
try {
174+
blob.downloadRangeToByteArray(0, (long) buffer.length, buffer, 0, null, options, null);
175+
fail("Expect exception");
176+
}
177+
catch (StorageException e) {
178+
assertEquals(SR.ENCRYPTION_DATA_NOT_PRESENT_ERROR, e.getMessage());
179+
}
180+
}
181+
147182
@Test
148183
public void testBlobEncryptionWithFile() throws URISyntaxException, StorageException, IOException,
149184
InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {

microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlobClientTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,11 @@ public void testSingleBlobPutThresholdInBytes() throws URISyntaxException, Stora
247247
try {
248248
bClient.getDefaultRequestOptions().setSingleBlobPutThresholdInBytes(
249249
BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES + 1);
250-
fail("Cannot set upload blob threshold above 64 MB");
250+
fail("Cannot set upload blob threshold above 256 MB");
251251
}
252252
catch (IllegalArgumentException e) {
253253
assertEquals(
254-
"The argument is out of range. Argument name: singleBlobPutThresholdInBytes, Value passed: 67108865.",
254+
"The argument is out of range. Argument name: singleBlobPutThresholdInBytes, Value passed: 268435457.",
255255
e.getMessage());
256256
}
257257

microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudBlockBlobTests.java

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
import com.microsoft.azure.storage.file.SharedAccessFilePermissions;
3434
import com.microsoft.azure.storage.file.SharedAccessFilePolicy;
3535

36-
import junit.framework.Assert;
37-
3836
import org.junit.After;
3937
import org.junit.Before;
4038
import org.junit.Test;
@@ -60,33 +58,11 @@
6058
import java.util.Random;
6159
import java.util.TimeZone;
6260

63-
import org.junit.After;
64-
import org.junit.Before;
65-
import org.junit.Test;
66-
import org.junit.experimental.categories.Category;
67-
68-
import com.microsoft.azure.storage.AccessCondition;
69-
import com.microsoft.azure.storage.Constants;
70-
import com.microsoft.azure.storage.NameValidator;
71-
import com.microsoft.azure.storage.OperationContext;
72-
import com.microsoft.azure.storage.RetryNoRetry;
73-
import com.microsoft.azure.storage.SendingRequestEvent;
74-
import com.microsoft.azure.storage.StorageCredentialsAnonymous;
75-
import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature;
7661
import com.microsoft.azure.storage.StorageErrorCodeStrings;
77-
import com.microsoft.azure.storage.StorageEvent;
78-
import com.microsoft.azure.storage.StorageException;
7962
import com.microsoft.azure.storage.TestRunners.CloudTests;
8063
import com.microsoft.azure.storage.TestRunners.DevFabricTests;
8164
import com.microsoft.azure.storage.TestRunners.DevStoreTests;
8265
import com.microsoft.azure.storage.TestRunners.SlowTests;
83-
import com.microsoft.azure.storage.core.Utility;
84-
import com.microsoft.azure.storage.file.CloudFile;
85-
import com.microsoft.azure.storage.file.CloudFileShare;
86-
import com.microsoft.azure.storage.file.FileProperties;
87-
import com.microsoft.azure.storage.file.FileTestHelper;
88-
import com.microsoft.azure.storage.file.SharedAccessFilePermissions;
89-
import com.microsoft.azure.storage.file.SharedAccessFilePolicy;
9066

9167
import static org.junit.Assert.*;
9268

@@ -1018,6 +994,44 @@ public void testLargeBlobUploadFromStreamTest() throws URISyntaxException, Stora
1018994
blockBlobRef.download(dstStream);
1019995
BlobTestHelper.assertStreamsAreEqual(srcStream, new ByteArrayInputStream(dstStream.toByteArray()));
1020996
}
997+
998+
@Test
999+
@Category({ DevFabricTests.class, DevStoreTests.class, SlowTests.class })
1000+
public void testLargeSinglePutBlobTest() throws URISyntaxException, StorageException, IOException {
1001+
final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
1002+
final String blockBlobName2 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
1003+
final String blockBlobName3 = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
1004+
final CloudBlockBlob blob = this.container.getBlockBlobReference(blockBlobName);
1005+
final CloudBlockBlob blob2 = this.container.getBlockBlobReference(blockBlobName2);
1006+
final CloudBlockBlob blob3 = this.container.getBlockBlobReference(blockBlobName3);
1007+
BlobRequestOptions options = new BlobRequestOptions();
1008+
options.setStoreBlobContentMD5(false);
1009+
options.setEncryptionPolicy(null);
1010+
try
1011+
{
1012+
byte[] buffer = BlobTestHelper.getRandomBuffer(256 * Constants.MB);
1013+
1014+
OperationContext operationContext = new OperationContext();
1015+
1016+
blob.uploadFromByteArray(buffer, 0, 128 * Constants.MB, null, null, operationContext);
1017+
assertEquals(1, operationContext.getRequestResults().size());
1018+
1019+
options.setSingleBlobPutThresholdInBytes(256 * Constants.MB);
1020+
blob2.uploadFromByteArray(buffer, 0, 256 * Constants.MB, null, options, operationContext);
1021+
assertEquals(1, operationContext.getRequestResults().size());
1022+
1023+
// Reduce threshold and upload data greater than the single put blob upload threshold
1024+
options.setSingleBlobPutThresholdInBytes(Constants.MB);
1025+
blob3.uploadFromByteArray(buffer, 0, 3 * Constants.MB, null, options, operationContext);
1026+
assertTrue(operationContext.getRequestResults().size() > 1);
1027+
}
1028+
finally
1029+
{
1030+
blob.delete();
1031+
blob2.delete();
1032+
blob3.delete();
1033+
}
1034+
}
10211035

10221036
@Test
10231037
@Category({ DevFabricTests.class, DevStoreTests.class })
@@ -1159,6 +1173,29 @@ public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, Stor
11591173
assertEquals("MDAwMDAwMDA=", blockBlobRef2.properties.getContentMD5());
11601174
}
11611175

1176+
@Test
1177+
@Category({ DevFabricTests.class, DevStoreTests.class })
1178+
public void testVerifyTransactionalMD5ValidationMissingOverallMD5() throws URISyntaxException, StorageException, IOException {
1179+
final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
1180+
final CloudBlockBlob blockBlobRef = this.container.getBlockBlobReference(blockBlobName);
1181+
1182+
final int length = 2 * 1024 * 1024;
1183+
ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length);
1184+
BlobRequestOptions options = new BlobRequestOptions();
1185+
options.setSingleBlobPutThresholdInBytes(1024*1024);
1186+
options.setDisableContentMD5Validation(true);
1187+
options.setStoreBlobContentMD5(false);
1188+
1189+
blockBlobRef.upload(srcStream, -1, null, options, null);
1190+
1191+
options.setDisableContentMD5Validation(false);
1192+
options.setStoreBlobContentMD5(true);
1193+
options.setUseTransactionalContentMD5(true);
1194+
final CloudBlockBlob blockBlobRef2 = this.container.getBlockBlobReference(blockBlobName);
1195+
blockBlobRef2.downloadRange(1024, (long)1024, new ByteArrayOutputStream(), null, options, null);
1196+
assertNull(blockBlobRef2.getProperties().getContentMD5());
1197+
}
1198+
11621199
@Test
11631200
@Category({ DevFabricTests.class, DevStoreTests.class })
11641201
public void testBlockBlobUploadContentMD5() throws URISyntaxException, StorageException, IOException {
@@ -1198,7 +1235,7 @@ public void eventOccurred(SendingRequestEvent eventArg) {
11981235
}
11991236
};
12001237

1201-
length = 33 * Constants.MB;
1238+
length = BlobConstants.DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES + 1;
12021239
srcStream = BlobTestHelper.getRandomDataStream(length);
12031240

12041241
sendingRequestEventContext.getSendingRequestEventHandler().addListener(event);
@@ -1709,6 +1746,23 @@ public void testBlobConditionalAccess() throws StorageException, IOException, UR
17091746
newETag = blob.getProperties().getEtag();
17101747
assertFalse("ETage should be modified on write metadata", newETag.equals(currentETag));
17111748
}
1749+
1750+
@Test
1751+
public void testBlobExceedMaxRange() throws URISyntaxException, StorageException, IOException
1752+
{
1753+
CloudBlockBlob blob = container.getBlockBlobReference("blockblob4");
1754+
blob.deleteIfExists();
1755+
1756+
byte[] msg = "my message".getBytes("UTF-8");
1757+
blob.uploadFromByteArray(msg, 0, msg.length);
1758+
1759+
byte[] buffer = new byte[msg.length + 5];
1760+
1761+
blob.downloadRangeToByteArray(0, (long) buffer.length, buffer, 0, null, null, null);
1762+
String expected = new String (msg, "UTF-8");
1763+
String actual = new String(buffer, "UTF-8").substring(0, 10);
1764+
assertEquals(expected, actual);
1765+
}
17121766

17131767
@Test
17141768
@Category({ DevFabricTests.class, DevStoreTests.class })

microsoft-azure-storage-test/src/com/microsoft/azure/storage/blob/CloudPageBlobTests.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,32 @@ public void testPageBlobDownloadRangeValidationTest() throws StorageException, U
211211
assertEquals(100, downloadLength);
212212
}
213213

214+
/**
215+
* Test requesting stored content MD5 with OpenWriteExisting().
216+
*
217+
* @throws URISyntaxException
218+
* @throws StorageException
219+
*/
220+
@Test
221+
public void testPageOpenWriteExistingWithMD5() throws URISyntaxException, StorageException, IOException {
222+
final String pageBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testPageBlob");
223+
final CloudPageBlob pageBlobRef = this.container.getPageBlobReference(pageBlobName);
224+
pageBlobRef.create(512);
225+
226+
BlobRequestOptions options = new BlobRequestOptions();
227+
options.setStoreBlobContentMD5(true);
228+
options.setDisableContentMD5Validation(false);
229+
230+
try
231+
{
232+
pageBlobRef.openWriteExisting(null, options, null);
233+
fail("Expect failure due to requesting MD5 calculation");
234+
}
235+
catch (IllegalArgumentException e)
236+
{
237+
}
238+
}
239+
214240
@Test
215241
public void testPageBlobUploadFromStreamTest() throws URISyntaxException, StorageException, IOException {
216242
final String pageBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testPageBlob");

microsoft-azure-storage-test/src/com/microsoft/azure/storage/file/CloudFileClientTests.java

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
import java.net.URISyntaxException;
3030
import java.util.ArrayList;
31+
import java.util.EnumSet;
32+
import java.util.HashMap;
3133
import java.util.UUID;
3234

3335
import static org.junit.Assert.*;
@@ -64,8 +66,8 @@ public void testListSharesTest() throws StorageException, URISyntaxException {
6466
ResultContinuation token = null;
6567
do {
6668

67-
ResultSegment<CloudFileShare> segment = fileClient.listSharesSegmented(prefix, ShareListingDetails.ALL,
68-
15, token, null, null);
69+
ResultSegment<CloudFileShare> segment = fileClient.listSharesSegmented(prefix,
70+
EnumSet.allOf(ShareListingDetails.class), 15, token, null, null);
6971

7072
for (final CloudFileShare share : segment.getResults()) {
7173
share.downloadAttributes();
@@ -102,7 +104,7 @@ public void testListSharesMaxResultsValidationTest() throws StorageException, UR
102104
for (int i = 0; i >= -2; i--) {
103105
try{
104106
fileClient.listSharesSegmented(
105-
prefix, ShareListingDetails.ALL, i, null, null, null);
107+
prefix, EnumSet.allOf(ShareListingDetails.class), i, null, null, null);
106108
fail();
107109
}
108110
catch (IllegalArgumentException e) {
@@ -112,4 +114,47 @@ public void testListSharesMaxResultsValidationTest() throws StorageException, UR
112114
}
113115
assertNotNull(fileClient.listSharesSegmented("thereshouldntbeanyshareswiththisprefix"));
114116
}
117+
118+
//@Test
119+
public void testListSharesWithSnapshot() throws StorageException, URISyntaxException {
120+
CloudFileClient fileClient = FileTestHelper.createCloudFileClient();
121+
CloudFileShare share = fileClient.getShareReference(UUID.randomUUID().toString());
122+
share.create();
123+
124+
HashMap<String, String> shareMeta = new HashMap<String, String>();
125+
shareMeta.put("key1", "value1");
126+
share.setMetadata(shareMeta);
127+
share.uploadMetadata();
128+
129+
CloudFileShare snapshot = share.createSnapshot();
130+
HashMap<String, String> meta2 = new HashMap<String, String>();
131+
meta2.put("key2", "value2");
132+
share.setMetadata(meta2);
133+
share.uploadMetadata();
134+
135+
CloudFileClient client = FileTestHelper.createCloudFileClient();
136+
Iterable<CloudFileShare> listResult = client.listShares(share.name, EnumSet.allOf(ShareListingDetails.class), null, null);
137+
138+
int count = 0;
139+
boolean originalFound = false;
140+
boolean snapshotFound = false;
141+
for (CloudFileShare listShareItem : listResult) {
142+
if (listShareItem.getName().equals(share.getName()) && !listShareItem.isSnapshot() && !originalFound)
143+
{
144+
count++;
145+
originalFound = true;
146+
assertEquals(share.getMetadata(), listShareItem.getMetadata());
147+
assertEquals(share.getStorageUri(), listShareItem.getStorageUri());
148+
}
149+
else if (listShareItem.getName().equals(share.getName()) &&
150+
listShareItem.isSnapshot() && !snapshotFound) {
151+
count++;
152+
snapshotFound = true;
153+
assertEquals(snapshot.getMetadata(), listShareItem.getMetadata());
154+
assertEquals(snapshot.getStorageUri(), listShareItem.getStorageUri());
155+
}
156+
}
157+
158+
assertEquals(2, count);
159+
}
115160
}

0 commit comments

Comments
 (0)