Skip to content

Commit

Permalink
Merge pull request Azure#152 from Azure/master
Browse files Browse the repository at this point in the history
5.1.0 Release
  • Loading branch information
erezvani1529 authored May 5, 2017
2 parents b8618be + 0b8a579 commit 04d68e1
Show file tree
Hide file tree
Showing 31 changed files with 1,304 additions and 184 deletions.
11 changes: 3 additions & 8 deletions BreakingChanges.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
Changes in X.X.X

BLOB/FILE
* Fixed a bug which allowed setting content MD5 to true when calling openWriteExisting() on a page blob or file.

Changes in 5.0.0
Changes in 5.0.0

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

FILE
FILE
* Fixed a bug where copying from a blob that included a SAS token and a snapshot did not use the SAS token.

QUEUE
Expand Down
6 changes: 5 additions & 1 deletion ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
2017.XX.XX Version X.X.X
2017.05.04 Version 5.1.0
* Fixed Exists() calls on Shares and Directories to now populate metadata. This was already being done for Files.
* 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.
* Fixed a bug that prevented setting content MD5 to true when creating a new file.
* Fixed a bug where access conditions, options, and operation context were not being passed when calling openWriteExisting() on a page blob or a file.
* 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.
* Fixed a bug where retries were happening immediately if a socket exception was thrown.
* In CloudFileShareProperties, setShareQuota() no longer asserts in bounds. This check has been moved to create() and uploadProperties() in CloudFileShare.

2017.01.18 Version 5.0.0
* Prefix support for listing files and directories.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,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>5.0.0</version>
<version>5.1.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 @@ -26,7 +26,7 @@
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage</artifactId>
<version>5.0.0</version>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
Expand Down Expand Up @@ -143,7 +144,41 @@ else if (type == BlobType.APPEND_BLOB) {
TestHelper.assertStreamsAreEqualAtIndex(stream, new ByteArrayInputStream(outputStream.toByteArray()), 0, 0,
size, 2 * 1024);
}


@Test
public void testDownloadUnencryptedBlobWithEncryptionPolicy() throws StorageException, IOException, URISyntaxException, NoSuchAlgorithmException
{
String blobName = BlobTestHelper.generateRandomBlobNameWithPrefix("test");
CloudBlockBlob blob = container.getBlockBlobReference(blobName);
blob.deleteIfExists();

byte[] msg = "my message".getBytes();
// Upload data without encryption
blob.uploadFromByteArray(msg, 0, msg.length);

// Create options with encryption policy
BlobRequestOptions options = new BlobRequestOptions();
options.setEncryptionPolicy(new BlobEncryptionPolicy(new RsaKey("myKey", 1024), null));
options.setRequireEncryption(true);

try {
blob.downloadText(Charset.defaultCharset().name(), null, options, null);
fail("Expect exception");
}
catch (StorageException e) {
assertEquals(SR.ENCRYPTION_DATA_NOT_PRESENT_ERROR, e.getMessage());
}

byte[] buffer = new byte[msg.length];
try {
blob.downloadRangeToByteArray(0, (long) buffer.length, buffer, 0, null, options, null);
fail("Expect exception");
}
catch (StorageException e) {
assertEquals(SR.ENCRYPTION_DATA_NOT_PRESENT_ERROR, e.getMessage());
}
}

@Test
public void testBlobEncryptionWithFile() throws URISyntaxException, StorageException, IOException,
InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
import com.microsoft.azure.storage.file.SharedAccessFilePermissions;
import com.microsoft.azure.storage.file.SharedAccessFilePolicy;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -60,33 +58,11 @@
import java.util.Random;
import java.util.TimeZone;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.microsoft.azure.storage.AccessCondition;
import com.microsoft.azure.storage.Constants;
import com.microsoft.azure.storage.NameValidator;
import com.microsoft.azure.storage.OperationContext;
import com.microsoft.azure.storage.RetryNoRetry;
import com.microsoft.azure.storage.SendingRequestEvent;
import com.microsoft.azure.storage.StorageCredentialsAnonymous;
import com.microsoft.azure.storage.StorageCredentialsSharedAccessSignature;
import com.microsoft.azure.storage.StorageErrorCodeStrings;
import com.microsoft.azure.storage.StorageEvent;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.TestRunners.CloudTests;
import com.microsoft.azure.storage.TestRunners.DevFabricTests;
import com.microsoft.azure.storage.TestRunners.DevStoreTests;
import com.microsoft.azure.storage.TestRunners.SlowTests;
import com.microsoft.azure.storage.core.Utility;
import com.microsoft.azure.storage.file.CloudFile;
import com.microsoft.azure.storage.file.CloudFileShare;
import com.microsoft.azure.storage.file.FileProperties;
import com.microsoft.azure.storage.file.FileTestHelper;
import com.microsoft.azure.storage.file.SharedAccessFilePermissions;
import com.microsoft.azure.storage.file.SharedAccessFilePolicy;

import static org.junit.Assert.*;

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

@Test
@Category({ DevFabricTests.class, DevStoreTests.class })
public void testVerifyTransactionalMD5ValidationMissingOverallMD5() throws URISyntaxException, StorageException, IOException {
final String blockBlobName = BlobTestHelper.generateRandomBlobNameWithPrefix("testBlockBlob");
final CloudBlockBlob blockBlobRef = this.container.getBlockBlobReference(blockBlobName);

final int length = 2 * 1024 * 1024;
ByteArrayInputStream srcStream = BlobTestHelper.getRandomDataStream(length);
BlobRequestOptions options = new BlobRequestOptions();
options.setSingleBlobPutThresholdInBytes(1024*1024);
options.setDisableContentMD5Validation(true);
options.setStoreBlobContentMD5(false);

blockBlobRef.upload(srcStream, -1, null, options, null);

options.setDisableContentMD5Validation(false);
options.setStoreBlobContentMD5(true);
options.setUseTransactionalContentMD5(true);
final CloudBlockBlob blockBlobRef2 = this.container.getBlockBlobReference(blockBlobName);
blockBlobRef2.downloadRange(1024, (long)1024, new ByteArrayOutputStream(), null, options, null);
assertNull(blockBlobRef2.getProperties().getContentMD5());
}

@Test
@Category({ DevFabricTests.class, DevStoreTests.class })
public void testBlockBlobUploadContentMD5() throws URISyntaxException, StorageException, IOException {
Expand Down Expand Up @@ -1747,6 +1746,23 @@ public void testBlobConditionalAccess() throws StorageException, IOException, UR
newETag = blob.getProperties().getEtag();
assertFalse("ETage should be modified on write metadata", newETag.equals(currentETag));
}

@Test
public void testBlobExceedMaxRange() throws URISyntaxException, StorageException, IOException
{
CloudBlockBlob blob = container.getBlockBlobReference("blockblob4");
blob.deleteIfExists();

byte[] msg = "my message".getBytes("UTF-8");
blob.uploadFromByteArray(msg, 0, msg.length);

byte[] buffer = new byte[msg.length + 5];

blob.downloadRangeToByteArray(0, (long) buffer.length, buffer, 0, null, null, null);
String expected = new String (msg, "UTF-8");
String actual = new String(buffer, "UTF-8").substring(0, 10);
assertEquals(expected, actual);
}

@Test
@Category({ DevFabricTests.class, DevStoreTests.class })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.UUID;

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

ResultSegment<CloudFileShare> segment = fileClient.listSharesSegmented(prefix, ShareListingDetails.ALL,
15, token, null, null);
ResultSegment<CloudFileShare> segment = fileClient.listSharesSegmented(prefix,
ShareListingDetails.ALL, 15, token, null, null);

for (final CloudFileShare share : segment.getResults()) {
share.downloadAttributes();
Expand Down Expand Up @@ -112,4 +114,47 @@ public void testListSharesMaxResultsValidationTest() throws StorageException, UR
}
assertNotNull(fileClient.listSharesSegmented("thereshouldntbeanyshareswiththisprefix"));
}

//@Test
public void testListSharesWithSnapshot() throws StorageException, URISyntaxException {
CloudFileClient fileClient = FileTestHelper.createCloudFileClient();
CloudFileShare share = fileClient.getShareReference(UUID.randomUUID().toString());
share.create();

HashMap<String, String> shareMeta = new HashMap<String, String>();
shareMeta.put("key1", "value1");
share.setMetadata(shareMeta);
share.uploadMetadata();

CloudFileShare snapshot = share.createSnapshot();
HashMap<String, String> meta2 = new HashMap<String, String>();
meta2.put("key2", "value2");
share.setMetadata(meta2);
share.uploadMetadata();

CloudFileClient client = FileTestHelper.createCloudFileClient();
Iterable<CloudFileShare> listResult = client.listShares(share.name, ShareListingDetails.ALL, null, null);

int count = 0;
boolean originalFound = false;
boolean snapshotFound = false;
for (CloudFileShare listShareItem : listResult) {
if (listShareItem.getName().equals(share.getName()) && !listShareItem.isSnapshot() && !originalFound)
{
count++;
originalFound = true;
assertEquals(share.getMetadata(), listShareItem.getMetadata());
assertEquals(share.getStorageUri(), listShareItem.getStorageUri());
}
else if (listShareItem.getName().equals(share.getName()) &&
listShareItem.isSnapshot() && !snapshotFound) {
count++;
snapshotFound = true;
assertEquals(snapshot.getMetadata(), listShareItem.getMetadata());
assertEquals(snapshot.getStorageUri(), listShareItem.getStorageUri());
}
}

assertEquals(2, count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
import com.microsoft.azure.storage.TestRunners.DevStoreTests;
import com.microsoft.azure.storage.core.PathUtility;
import com.microsoft.azure.storage.core.SR;
import com.microsoft.azure.storage.core.UriQueryBuilder;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;

import org.junit.After;
import org.junit.Assert;
Expand Down Expand Up @@ -460,7 +462,7 @@ public void testCloudFileDirectoryInvalidMetadata() throws StorageException, URI
testMetadataFailures(directory, "key1", "\n \t", false);
}

private static void testMetadataFailures(CloudFileDirectory directory, String key, String value, boolean badKey) {
private static void testMetadataFailures(CloudFileDirectory directory, String key, String value, boolean badKey) throws URISyntaxException {
directory.getMetadata().put(key, value);
try {
directory.uploadMetadata();
Expand All @@ -478,6 +480,71 @@ private static void testMetadataFailures(CloudFileDirectory directory, String ke
directory.getMetadata().remove(key);
}

//@Test
public void testUnsupportedDirectoryApisWithinShareSnapshot() throws StorageException, URISyntaxException {
CloudFileShare snapshot = this.share.createSnapshot();
CloudFileDirectory rootDir = snapshot.getRootDirectoryReference();
try {
rootDir.create();
fail("Shouldn't get here");
}
catch (IllegalArgumentException e) {
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
}
try {
rootDir.delete();
fail("Shouldn't get here");
}
catch (IllegalArgumentException e) {
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
}
try {
rootDir.uploadMetadata();
fail("Shouldn't get here");
}
catch (IllegalArgumentException e) {
assertEquals(SR.INVALID_OPERATION_FOR_A_SHARE_SNAPSHOT, e.getMessage());
}

snapshot.delete();
}

//@Test
public void testSupportedDirectoryApisInShareSnapshot() throws StorageException, URISyntaxException {
CloudFileDirectory dir = this.share.getRootDirectoryReference().getDirectoryReference("dir1");
dir.deleteIfExists();
dir.create();
HashMap<String, String> meta = new HashMap<String, String>();
meta.put("key1", "value1");
dir.setMetadata(meta);
dir.uploadMetadata();
CloudFileShare snapshot = this.share.createSnapshot();
CloudFileDirectory snapshotDir = snapshot.getRootDirectoryReference().getDirectoryReference("dir1");

HashMap<String, String> meta2 = new HashMap<String, String>();
meta2.put("key2", "value2");
dir.setMetadata(meta2);
dir.uploadMetadata();
snapshotDir.downloadAttributes();

assertTrue(snapshotDir.getMetadata().size() == 1 && snapshotDir.getMetadata().get("key1").equals("value1"));
assertNotNull(snapshotDir.getProperties().getEtag());

dir.downloadAttributes();
assertTrue(dir.getMetadata().size() == 1 && dir.getMetadata().get("key2").equals("value2"));
assertNotNull(dir.getProperties().getEtag());
assertNotEquals(dir.getProperties().getEtag(), snapshotDir.getProperties().getEtag());

final UriQueryBuilder uriBuilder = new UriQueryBuilder();
uriBuilder.add("sharesnapshot", snapshot.snapshotID);
uriBuilder.add("restype", "directory");
CloudFileDirectory snapshotDir2 = new CloudFileDirectory(uriBuilder.addToURI(dir.getUri()), this.share.getServiceClient().getCredentials());
assertEquals(snapshot.snapshotID, snapshotDir2.getShare().snapshotID);
assertTrue(snapshotDir2.exists());

snapshot.delete();
}

/*
[TestMethod]
[Description("CloudFileDirectory deleting a directory using conditional access")]
Expand Down Expand Up @@ -807,6 +874,8 @@ public void eventOccurred(SendingRequestEvent eventArg) {
}
catch (StorageException e) {
fail("Delete should succeed.");
} catch (URISyntaxException e) {
fail("Delete should succeed.");
}
}
}
Expand Down
Loading

0 comments on commit 04d68e1

Please sign in to comment.