From 8c9a38d239e7c3b35e3d523aa2fd50d953ed9434 Mon Sep 17 00:00:00 2001 From: Rob Block Date: Fri, 14 Jun 2019 16:21:47 -0700 Subject: [PATCH] Azure container name must be lower case (#1192) --- .../azure/AzureCloudDestination.java | 20 ++++++++++++++----- .../azure/AzureIntegrationTest.java | 11 ++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ambry-cloud/src/main/java/com.github.ambry.cloud/azure/AzureCloudDestination.java b/ambry-cloud/src/main/java/com.github.ambry.cloud/azure/AzureCloudDestination.java index e7d077a3ca..4f8770d18c 100644 --- a/ambry-cloud/src/main/java/com.github.ambry.cloud/azure/AzureCloudDestination.java +++ b/ambry-cloud/src/main/java/com.github.ambry.cloud/azure/AzureCloudDestination.java @@ -402,10 +402,18 @@ private CloudBlobContainer getContainer(BlobId blobId, boolean autoCreate) * @throws StorageException if the operation fails. */ private void ensureCreated(CloudBlobContainer azureContainer) throws StorageException { - if (!knownContainers.contains(azureContainer.getName())) { - azureContainer.createIfNotExists(BlobContainerPublicAccessType.CONTAINER, new BlobRequestOptions(), - blobOpContext); - knownContainers.add(azureContainer.getName()); + String containerName = azureContainer.getName(); + if (!knownContainers.contains(containerName)) { + try { + if (azureContainer.createIfNotExists(BlobContainerPublicAccessType.CONTAINER, new BlobRequestOptions(), + blobOpContext)) { + logger.info("Created container {}", containerName); + } + } catch (StorageException ex) { + logger.error("Failed to create container {}", containerName); + throw ex; + } + knownContainers.add(containerName); } } @@ -447,7 +455,9 @@ public boolean retrieveTokens(String partitionPath, String tokenFileName, Output */ String getAzureContainerName(String partitionPath) { // Include Ambry cluster name in case the same storage account is used to backup multiple clusters. - return clusterName + SEPARATOR + partitionPath; + // Azure requires container names to be all lower case + String rawContainerName = clusterName + SEPARATOR + partitionPath; + return rawContainerName.toLowerCase(); } /** diff --git a/ambry-cloud/src/test/java/com.github.ambry.cloud/azure/AzureIntegrationTest.java b/ambry-cloud/src/test/java/com.github.ambry.cloud/azure/AzureIntegrationTest.java index f0089f9055..6cc083c12b 100644 --- a/ambry-cloud/src/test/java/com.github.ambry.cloud/azure/AzureIntegrationTest.java +++ b/ambry-cloud/src/test/java/com.github.ambry.cloud/azure/AzureIntegrationTest.java @@ -67,6 +67,7 @@ public class AzureIntegrationTest { private byte dataCenterId = 66; private short accountId = 101; private short containerId = 5; + private long testPartition = 666; private String cosmosCollectionLink; private String propFileName = "azure-test.properties"; private String tokenFileName = "replicaTokens"; @@ -82,6 +83,9 @@ public void setup() throws Exception { } catch (IOException ex) { throw new IllegalStateException("Could not load properties from resource: " + propFileName); } + props.setProperty("clustermap.cluster.name", "Integration-Test"); + props.setProperty("clustermap.datacenter.name", "uswest"); + props.setProperty("clustermap.host.name", "localhost"); VerifiableProperties verProps = new VerifiableProperties(props); azureDest = (AzureCloudDestination) new AzureCloudDestinationFactory(verProps, new MetricRegistry()).getCloudDestination(); @@ -94,7 +98,7 @@ public void setup() throws Exception { */ @Test public void testNormalFlow() throws Exception { - PartitionId partitionId = new MockPartitionId(); + PartitionId partitionId = new MockPartitionId(testPartition, MockClusterMap.DEFAULT_PARTITION_CLASS); BlobId blobId = new BlobId(BLOB_ID_V6, BlobIdType.NATIVE, dataCenterId, accountId, containerId, partitionId, false, BlobDataType.DATACHUNK); InputStream inputStream = getBlobInputStream(blobSize); @@ -125,8 +129,7 @@ public void testNormalFlow() throws Exception { @Test public void testBatchQuery() throws Exception { int numBlobs = 100; - long partition = 666; - PartitionId partitionId = new MockPartitionId(partition, MockClusterMap.DEFAULT_PARTITION_CLASS); + PartitionId partitionId = new MockPartitionId(testPartition, MockClusterMap.DEFAULT_PARTITION_CLASS); List blobIdList = new ArrayList<>(); long creationTime = System.currentTimeMillis(); for (int j = 0; j < numBlobs; j++) { @@ -178,7 +181,7 @@ public void testBatchQuery() throws Exception { /** Persist tokens to Azure, then read them back and verify they match. */ @Test public void testTokens() throws Exception { - String partitionPath = "666"; + String partitionPath = String.valueOf(testPartition); InputStream input = this.getClass().getClassLoader().getResourceAsStream(tokenFileName); if (input == null) { throw new IllegalStateException("Could not find resource: " + tokenFileName);