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

Commit 04d68e1

Browse files
authored
Merge pull request #152 from Azure/master
5.1.0 Release
2 parents b8618be + 0b8a579 commit 04d68e1

31 files changed

+1304
-184
lines changed

BreakingChanges.txt

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
Changes in X.X.X
2-
3-
BLOB/FILE
4-
* Fixed a bug which allowed setting content MD5 to true when calling openWriteExisting() on a page blob or file.
5-
6-
Changes in 5.0.0
1+
Changes in 5.0.0
72

83
BLOB
94
* getQualifiedUri() has been deprecated. Please use getSnapshotQualifiedUri() instead. This new function will return the blob including the snapshot (if present) and no SAS token.
105
* getQualifiedStorageUri() has been deprecated. Please use getSnapshotQualifiedStorageUri() instead. This new function will return the blob including the snapshot (if present) and no SAS token.
116
* Fixed a bug where copying from a blob that included a SAS token and a snapshot did not use the SAS token.
12-
13-
FILE
7+
8+
FILE
149
* Fixed a bug where copying from a blob that included a SAS token and a snapshot did not use the SAS token.
1510

1611
QUEUE

ChangeLog.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
2017.XX.XX Version X.X.X
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.
23
* 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.
34
* Fixed a bug that prevented setting content MD5 to true when creating a new file.
45
* 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 socket exception was thrown.
8+
* In CloudFileShareProperties, setShareQuota() no longer asserts in bounds. This check has been moved to create() and uploadProperties() in CloudFileShare.
59

610
2017.01.18 Version 5.0.0
711
* Prefix support for listing files and directories.

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/CloudBlockBlobTests.java

Lines changed: 40 additions & 24 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

@@ -1197,6 +1173,29 @@ public void testBlobUploadWithoutMD5Validation() throws URISyntaxException, Stor
11971173
assertEquals("MDAwMDAwMDA=", blockBlobRef2.properties.getContentMD5());
11981174
}
11991175

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+
12001199
@Test
12011200
@Category({ DevFabricTests.class, DevStoreTests.class })
12021201
public void testBlockBlobUploadContentMD5() throws URISyntaxException, StorageException, IOException {
@@ -1747,6 +1746,23 @@ public void testBlobConditionalAccess() throws StorageException, IOException, UR
17471746
newETag = blob.getProperties().getEtag();
17481747
assertFalse("ETage should be modified on write metadata", newETag.equals(currentETag));
17491748
}
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+
}
17501766

17511767
@Test
17521768
@Category({ DevFabricTests.class, DevStoreTests.class })

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

Lines changed: 47 additions & 2 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+
ShareListingDetails.ALL, 15, token, null, null);
6971

7072
for (final CloudFileShare share : segment.getResults()) {
7173
share.downloadAttributes();
@@ -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, ShareListingDetails.ALL, 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
}

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

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
import com.microsoft.azure.storage.TestRunners.DevStoreTests;
2828
import com.microsoft.azure.storage.core.PathUtility;
2929
import com.microsoft.azure.storage.core.SR;
30+
import com.microsoft.azure.storage.core.UriQueryBuilder;
3031

3132
import java.io.IOException;
3233
import java.net.HttpURLConnection;
3334
import java.net.URI;
3435
import java.net.URISyntaxException;
3536
import java.util.ArrayList;
37+
import java.util.HashMap;
3638

3739
import org.junit.After;
3840
import org.junit.Assert;
@@ -460,7 +462,7 @@ public void testCloudFileDirectoryInvalidMetadata() throws StorageException, URI
460462
testMetadataFailures(directory, "key1", "\n \t", false);
461463
}
462464

463-
private static void testMetadataFailures(CloudFileDirectory directory, String key, String value, boolean badKey) {
465+
private static void testMetadataFailures(CloudFileDirectory directory, String key, String value, boolean badKey) throws URISyntaxException {
464466
directory.getMetadata().put(key, value);
465467
try {
466468
directory.uploadMetadata();
@@ -478,6 +480,71 @@ private static void testMetadataFailures(CloudFileDirectory directory, String ke
478480
directory.getMetadata().remove(key);
479481
}
480482

483+
//@Test
484+
public void testUnsupportedDirectoryApisWithinShareSnapshot() throws StorageException, URISyntaxException {
485+
CloudFileShare snapshot = this.share.createSnapshot();
486+
CloudFileDirectory rootDir = snapshot.getRootDirectoryReference();
487+
try {
488+
rootDir.create();
489+
fail("Shouldn't get here");
490+
}
491+
catch (IllegalArgumentException e) {
492+
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
493+
}
494+
try {
495+
rootDir.delete();
496+
fail("Shouldn't get here");
497+
}
498+
catch (IllegalArgumentException e) {
499+
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
500+
}
501+
try {
502+
rootDir.uploadMetadata();
503+
fail("Shouldn't get here");
504+
}
505+
catch (IllegalArgumentException e) {
506+
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
507+
}
508+
509+
snapshot.delete();
510+
}
511+
512+
//@Test
513+
public void testSupportedDirectoryApisInShareSnapshot() throws StorageException, URISyntaxException {
514+
CloudFileDirectory dir = this.share.getRootDirectoryReference().getDirectoryReference("dir1");
515+
dir.deleteIfExists();
516+
dir.create();
517+
HashMap<String, String> meta = new HashMap<String, String>();
518+
meta.put("key1", "value1");
519+
dir.setMetadata(meta);
520+
dir.uploadMetadata();
521+
CloudFileShare snapshot = this.share.createSnapshot();
522+
CloudFileDirectory snapshotDir = snapshot.getRootDirectoryReference().getDirectoryReference("dir1");
523+
524+
HashMap<String, String> meta2 = new HashMap<String, String>();
525+
meta2.put("key2", "value2");
526+
dir.setMetadata(meta2);
527+
dir.uploadMetadata();
528+
snapshotDir.downloadAttributes();
529+
530+
assertTrue(snapshotDir.getMetadata().size() == 1 && snapshotDir.getMetadata().get("key1").equals("value1"));
531+
assertNotNull(snapshotDir.getProperties().getEtag());
532+
533+
dir.downloadAttributes();
534+
assertTrue(dir.getMetadata().size() == 1 && dir.getMetadata().get("key2").equals("value2"));
535+
assertNotNull(dir.getProperties().getEtag());
536+
assertNotEquals(dir.getProperties().getEtag(), snapshotDir.getProperties().getEtag());
537+
538+
final UriQueryBuilder uriBuilder = new UriQueryBuilder();
539+
uriBuilder.add("sharesnapshot", snapshot.snapshotID);
540+
uriBuilder.add("restype", "directory");
541+
CloudFileDirectory snapshotDir2 = new CloudFileDirectory(uriBuilder.addToURI(dir.getUri()), this.share.getServiceClient().getCredentials());
542+
assertEquals(snapshot.snapshotID, snapshotDir2.getShare().snapshotID);
543+
assertTrue(snapshotDir2.exists());
544+
545+
snapshot.delete();
546+
}
547+
481548
/*
482549
[TestMethod]
483550
[Description("CloudFileDirectory deleting a directory using conditional access")]
@@ -807,6 +874,8 @@ public void eventOccurred(SendingRequestEvent eventArg) {
807874
}
808875
catch (StorageException e) {
809876
fail("Delete should succeed.");
877+
} catch (URISyntaxException e) {
878+
fail("Delete should succeed.");
810879
}
811880
}
812881
}

0 commit comments

Comments
 (0)