/**
* Copyright Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.azure.storage;
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.blob.BlobRequestOptions;
import com.microsoft.azure.storage.blob.BlobTestHelper;
import com.microsoft.azure.storage.blob.BlobType;
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.blob.CloudPageBlob;
import com.microsoft.azure.storage.blob.DeleteSnapshotsOption;
import com.microsoft.azure.storage.queue.CloudQueue;
import com.microsoft.azure.storage.queue.CloudQueueClient;
import com.microsoft.azure.storage.queue.QueueRequestOptions;
import com.microsoft.azure.storage.queue.QueueTestHelper;
import com.microsoft.azure.storage.table.CloudTable;
import com.microsoft.azure.storage.table.CloudTableClient;
import com.microsoft.azure.storage.table.TableRequestOptions;
import com.microsoft.azure.storage.table.TableTestHelper;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
@Category({ SecondaryTests.class, DevFabricTests.class, DevStoreTests.class, CloudTests.class })
public class SecondaryTests {
@Test
public void testLocationModeWithMissingUri() throws URISyntaxException, StorageException {
CloudBlobClient client = TestHelper.createCloudBlobClient();
CloudBlobClient primaryOnlyClient = new CloudBlobClient(client.getEndpoint(), client.getCredentials());
CloudBlobContainer container = primaryOnlyClient.getContainerReference("nonexistingcontainer");
BlobRequestOptions options = new BlobRequestOptions();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
options.setRetryPolicyFactory(new RetryNoRetry());
try {
container.downloadAttributes(null, options, null);
fail();
}
catch (StorageException ex) {
assertEquals(UnsupportedOperationException.class, ex.getCause().getClass());
}
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
try {
container.downloadAttributes(null, options, null);
fail();
}
catch (StorageException ex) {
assertEquals(UnsupportedOperationException.class, ex.getCause().getClass());
}
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
try {
container.downloadAttributes(null, options, null);
fail();
}
catch (StorageException ex) {
assertEquals(UnsupportedOperationException.class, ex.getCause().getClass());
}
}
@Test
public void testBlobIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException {
CloudBlobContainer container = BlobTestHelper.getRandomContainerReference();
BlobRequestOptions options = new BlobRequestOptions();
// CreateIfNotExists
OperationContext context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
container.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
container.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
container.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
container.createIfNotExists(options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
// DeleteIfExists
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
container.deleteIfExists(null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
container.deleteIfExists(null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
container.deleteIfExists(null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
container.deleteIfExists(null, options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
CloudBlockBlob blockBlob = container.getBlockBlobReference("blob1");
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
blockBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
blockBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
blockBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
blockBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
CloudPageBlob pageBlob = container.getPageBlobReference("blob2");
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
pageBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
pageBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
pageBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
pageBlob.deleteIfExists(DeleteSnapshotsOption.NONE, null, options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
}
@Test
public void testQueueIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException {
CloudQueueClient client = TestHelper.createCloudQueueClient();
CloudQueue queue = client.getQueueReference("nonexistantqueue");
QueueRequestOptions options = new QueueRequestOptions();
// CreateIfNotExists
OperationContext context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
queue.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
queue.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
queue.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
queue.createIfNotExists(options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
// DeleteIfExists
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
queue.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
queue.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
queue.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
queue.deleteIfExists(options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
}
@Test
public void testTableIfExistsShouldNotHitSecondary() throws StorageException, URISyntaxException {
CloudTableClient client = TestHelper.createCloudTableClient();
CloudTable table = client.getTableReference("nonexistanttable");
TableRequestOptions options = new TableRequestOptions();
// CreateIfNotExists
OperationContext context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
table.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
table.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
table.createIfNotExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
table.createIfNotExists(options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
// DeleteIfExists
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_ONLY);
table.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.PRIMARY_THEN_SECONDARY);
table.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_THEN_PRIMARY);
table.deleteIfExists(options, context);
assertEquals(StorageLocation.PRIMARY, context.getRequestResults().get(0).getTargetLocation());
context = new OperationContext();
options.setLocationMode(LocationMode.SECONDARY_ONLY);
try {
table.deleteIfExists(options, context);
}
catch (StorageException ex) {
assertEquals(IllegalArgumentException.class, ex.getCause().getClass());
}
}
@Test
@Category(SlowTests.class)
public void testMultiLocationRetriesBlob() throws URISyntaxException, StorageException {
List<RetryInfo> retryInfoList = new ArrayList<RetryInfo>();
List<RetryContext> retryContextList = new ArrayList<RetryContext>();
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
// Next location is set to primary and location mode is primary only.
testContainerDownloadAttributes(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
// Next location is set to secondary and location mode is secondary only.
testContainerDownloadAttributes(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
// Next location is set to secondary and location mode is PRIMARY_THEN_SECONDARY.
testContainerDownloadAttributes(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
// Next location is set to primary and location mode is SECONDARY_THEN_PRIMARY.
testContainerDownloadAttributes(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testContainerDownloadAttributes(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testContainerDownloadAttributes(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.PRIMARY_THEN_SECONDARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.PRIMARY_THEN_SECONDARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testContainerDownloadAttributes(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.SECONDARY_THEN_PRIMARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.SECONDARY_THEN_PRIMARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testContainerDownloadAttributes(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testContainerDownloadAttributes(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
}
@Test
@Category(SlowTests.class)
public void testMultiLocationRetriesQueue() throws URISyntaxException, StorageException {
List<RetryInfo> retryInfoList = new ArrayList<RetryInfo>();
List<RetryContext> retryContextList = new ArrayList<RetryContext>();
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
// Next location is set to primary and location mode is primary only.
testQueueDownloadAttributes(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
// Next location is set to secondary and location mode is secondary only.
testQueueDownloadAttributes(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
// Next location is set to secondary and location mode is PRIMARY_THEN_SECONDARY.
testQueueDownloadAttributes(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
// Next location is set to primary and location mode is SECONDARY_THEN_PRIMARY.
testQueueDownloadAttributes(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testQueueDownloadAttributes(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testQueueDownloadAttributes(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.PRIMARY_THEN_SECONDARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.PRIMARY_THEN_SECONDARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testQueueDownloadAttributes(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.SECONDARY_THEN_PRIMARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.SECONDARY_THEN_PRIMARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testQueueDownloadAttributes(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testQueueDownloadAttributes(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
}
@Test
@Category(SlowTests.class)
public void testMultiLocationRetriesTable() throws URISyntaxException, StorageException {
List<RetryInfo> retryInfoList = new ArrayList<RetryInfo>();
List<RetryContext> retryContextList = new ArrayList<RetryContext>();
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
// Next location is set to primary and location mode is primary only.
testTableDownloadPermissions(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
// Next location is set to secondary and location mode is secondary only.
testTableDownloadPermissions(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
// Next location is set to secondary and location mode is PRIMARY_THEN_SECONDARY.
testTableDownloadPermissions(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
// Next location is set to primary and location mode is SECONDARY_THEN_PRIMARY.
testTableDownloadPermissions(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testTableDownloadPermissions(LocationMode.PRIMARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.PRIMARY_ONLY, StorageLocation.PRIMARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY,
1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testTableDownloadPermissions(LocationMode.SECONDARY_ONLY, LocationMode.PRIMARY_ONLY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.SECONDARY_ONLY, StorageLocation.SECONDARY, retryContextList,
retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.PRIMARY_THEN_SECONDARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.PRIMARY_THEN_SECONDARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.PRIMARY_THEN_SECONDARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testTableDownloadPermissions(LocationMode.PRIMARY_THEN_SECONDARY, LocationMode.PRIMARY_ONLY,
StorageLocation.PRIMARY, retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.PRIMARY_THEN_SECONDARY, StorageLocation.PRIMARY,
retryContextList, retryInfoList);
retryContextList.clear();
retryInfoList.clear();
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY,
LocationMode.SECONDARY_THEN_PRIMARY, 6000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_THEN_PRIMARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.SECONDARY_THEN_PRIMARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
AddUpdatedLocationModes(retryContextList, retryInfoList);
// Use AlwaysRetry and retry the request multiple times based on the retry context and retry info lists created above.
testTableDownloadPermissions(LocationMode.SECONDARY_THEN_PRIMARY, LocationMode.PRIMARY_ONLY,
StorageLocation.SECONDARY, retryContextList, retryInfoList);
testTableDownloadPermissions(null, LocationMode.SECONDARY_THEN_PRIMARY, StorageLocation.SECONDARY,
retryContextList, retryInfoList);
}
@Test
public void testRetryOn304() throws StorageException, IOException, URISyntaxException {
OperationContext operationContext = new OperationContext();
operationContext.getRetryingEventHandler().addListener(new StorageEvent<RetryingEvent>() {
@Override
public void eventOccurred(RetryingEvent eventArg) {
fail("Request should not be retried.");
}
});
CloudBlobContainer container = BlobTestHelper.getRandomContainerReference();
try {
container.create();
CloudBlockBlob blockBlobRef = (CloudBlockBlob) BlobTestHelper.uploadNewBlob(container, BlobType.BLOCK_BLOB,
"originalBlob", 1024, null);
AccessCondition accessCondition = AccessCondition.generateIfNoneMatchCondition(blockBlobRef.getProperties().getEtag());
blockBlobRef.download(new ByteArrayOutputStream(), accessCondition, null, operationContext);
fail("Download should fail with a 304.");
} catch (StorageException ex) {
assertEquals("The condition specified using HTTP conditional header(s) is not met.", ex.getMessage());
} finally {
container.deleteIfExists();
}
}
private static void AddUpdatedLocationModes(List<RetryContext> retryContextList, List<RetryInfo> retryInfoList) {
retryInfoList
.add(populateRetryInfo(new RetryInfo(), StorageLocation.PRIMARY, LocationMode.SECONDARY_ONLY, 4000));
retryContextList.add(new RetryContext(0, null, StorageLocation.SECONDARY, LocationMode.SECONDARY_ONLY));
retryInfoList
.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY, LocationMode.PRIMARY_ONLY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_ONLY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.PRIMARY_THEN_SECONDARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.PRIMARY_THEN_SECONDARY));
retryInfoList.add(populateRetryInfo(new RetryInfo(), StorageLocation.SECONDARY,
LocationMode.SECONDARY_THEN_PRIMARY, 1000));
retryContextList.add(new RetryContext(0, null, StorageLocation.PRIMARY, LocationMode.SECONDARY_THEN_PRIMARY));
}
private static RetryInfo populateRetryInfo(RetryInfo retryInfo, StorageLocation location,
LocationMode locationMode, int interval) {
retryInfo.setTargetLocation(location);
retryInfo.setUpdatedLocationMode(locationMode);
retryInfo.setRetryInterval(interval);
return retryInfo;
}
private static void testContainerDownloadAttributes(LocationMode optionsLocationMode,
LocationMode clientLocationMode, StorageLocation initialLocation, List<RetryContext> retryContextList,
List<RetryInfo> retryInfoList) throws URISyntaxException, StorageException {
CloudBlobContainer container = BlobTestHelper.getRandomContainerReference();
MultiLocationTestHelper helper = new MultiLocationTestHelper(container.getServiceClient().getStorageUri(),
initialLocation, retryContextList, retryInfoList);
container.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode);
BlobRequestOptions options = new BlobRequestOptions();
options.setLocationMode(optionsLocationMode);
options.setRetryPolicyFactory(helper.retryPolicy);
try {
container.downloadAttributes(null, options, helper.operationContext);
}
catch (StorageException ex) {
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, ex.getHttpStatusCode());
}
finally {
helper.close();
}
}
private static void testQueueDownloadAttributes(LocationMode optionsLocationMode, LocationMode clientLocationMode,
StorageLocation initialLocation, List<RetryContext> retryContextList, List<RetryInfo> retryInfoList)
throws URISyntaxException, StorageException {
CloudQueueClient client = TestHelper.createCloudQueueClient();
CloudQueue queue = client.getQueueReference(QueueTestHelper.generateRandomQueueName());
MultiLocationTestHelper helper = new MultiLocationTestHelper(queue.getServiceClient().getStorageUri(),
initialLocation, retryContextList, retryInfoList);
queue.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode);
QueueRequestOptions options = new QueueRequestOptions();
options.setLocationMode(optionsLocationMode);
options.setRetryPolicyFactory(helper.retryPolicy);
try {
queue.downloadAttributes(options, helper.operationContext);
}
catch (StorageException ex) {
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, ex.getHttpStatusCode());
}
finally {
helper.close();
}
}
private static void testTableDownloadPermissions(LocationMode optionsLocationMode, LocationMode clientLocationMode,
StorageLocation initialLocation, List<RetryContext> retryContextList, List<RetryInfo> retryInfoList)
throws URISyntaxException, StorageException {
CloudTableClient client = TestHelper.createCloudTableClient();
CloudTable table = client.getTableReference(TableTestHelper.generateRandomTableName());
MultiLocationTestHelper helper = new MultiLocationTestHelper(table.getServiceClient().getStorageUri(),
initialLocation, retryContextList, retryInfoList);
table.getServiceClient().getDefaultRequestOptions().setLocationMode(clientLocationMode);
TableRequestOptions options = new TableRequestOptions();
options.setLocationMode(optionsLocationMode);
options.setRetryPolicyFactory(helper.retryPolicy);
try {
table.downloadPermissions(options, helper.operationContext);
}
catch (StorageException ex) {
assertEquals(HttpURLConnection.HTTP_NOT_FOUND, ex.getHttpStatusCode());
}
finally {
helper.close();
}
}
}