Open
Description
Describe the bug
When migrating from the bom 1.2.23 to 1.2.24, the filename displayed when listing the blobs changed from dir/entity
to dir/%2Fentity
Exception or Stack Trace
java.lang.AssertionError:
Expecting actual:
["dir1%2Fentity2", "entity1"]
to contain exactly in any order:
["entity1", "dir1/entity2"]
elements not found:
["dir1/entity2"]
and elements not expected:
["dir1%2Fentity2"]
To Reproduce
You shoud provide:
- your connection string (method
getConnectionString()
which is not imported) - your encryption key (method
getEncryptionKey()
which is not imported) - your encryption algorithm (method
getKeyEncryptionAlgorithm()
which is not imported)
import static org.assertj.core.api.Assertions.assertThat;
import com.activeviam.cloud.test.internal.util.impl.CloudTestUtil;
import com.azure.core.cryptography.AsyncKeyEncryptionKey;
import com.azure.core.http.rest.PagedIterable;
import com.azure.security.keyvault.keys.cryptography.KeyEncryptionKeyClientBuilder;
import com.azure.security.keyvault.keys.models.JsonWebKey;
import com.azure.security.keyvault.keys.models.KeyOperation;
import com.azure.storage.blob.BlobContainerClient;
import com.azure.storage.blob.BlobServiceClient;
import com.azure.storage.blob.BlobServiceClientBuilder;
import com.azure.storage.blob.models.BlobItem;
import com.azure.storage.blob.models.ListBlobsOptions;
import com.azure.storage.blob.specialized.cryptography.EncryptedBlobClient;
import com.azure.storage.blob.specialized.cryptography.EncryptedBlobClientBuilder;
import com.azure.storage.blob.specialized.cryptography.EncryptionVersion;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.security.KeyPair;
import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class TestAzureUpdateWithEncryptedDirectory {
private static final String connectionString = getConnectionString();
private static BlobContainerClient CONTAINER;
private static final String CONTAINER_NAME = "TestAzureUpdateWithEncryptedDirectory".toLowerCase();
private static AsyncKeyEncryptionKey keyEncryptionKey;
private static String keyEncryptionAlgorithm;
@BeforeAll
public static void setUp() throws Exception {
BlobServiceClient client = new BlobServiceClientBuilder().connectionString(connectionString).buildClient();
initializeEncryptionCapabilities(
TestAzureUpdateWithEncryptedDirectory.class.getName(),
CloudTestUtil.getEncryptionKey(),
CloudTestUtil.getKeyEncryptionAlgorithm());
CONTAINER = client.getBlobContainerClient(CONTAINER_NAME);
CONTAINER.deleteIfExists(); // useful when rerunning the test to clean up the data from previous tests
Thread.sleep(Duration.ofSeconds(5)); // wait for deletion of the container
CONTAINER.create();
}
@Test
void testListEntitiesOnAzure() {
final String e1 = "entity1";
final String e2 = "dir1/entity2";
PagedIterable<BlobItem> blobs;
blobs = CONTAINER.listBlobs(new ListBlobsOptions().setPrefix(""), null);
assertThat(blobs.stream().map(BlobItem::getName)).isEmpty();
uploadData(e1, "1");
blobs = CONTAINER.listBlobs(new ListBlobsOptions().setPrefix(""), null);
assertThat(blobs.stream().map(BlobItem::getName)).containsExactlyInAnyOrder(e1);
uploadData(e2, "2");
blobs = CONTAINER.listBlobs(new ListBlobsOptions().setPrefix(""), null);
assertThat(blobs.stream().map(BlobItem::getName)).containsExactlyInAnyOrder(e1, e2);
}
private void uploadData(final String name, final String content) {
try {
final byte[] buffer = content.getBytes(Charset.defaultCharset());
final EncryptedBlobClient encryptionClient =
new EncryptedBlobClientBuilder(EncryptionVersion.V2)
.blobClient(CONTAINER.getBlobClient(name))
.key(keyEncryptionKey, keyEncryptionAlgorithm)
.buildEncryptedBlobClient();
encryptionClient.upload(new ByteArrayInputStream(buffer), buffer.length);
} catch (final Exception e) {
throw new RuntimeException(name, e);
}
}
private static void initializeEncryptionCapabilities(
final String keyId, final KeyPair keyPair, final String encryptionAlgorithm) {
keyEncryptionKey = buildKeyEncryptionKeyFrom(keyId, keyPair, List.of(KeyOperation.UNWRAP_KEY, KeyOperation.WRAP_KEY));
keyEncryptionAlgorithm = encryptionAlgorithm;
}
private static AsyncKeyEncryptionKey buildKeyEncryptionKeyFrom(
final String keyId, final KeyPair keyPair, final List<KeyOperation> authorizedOperations) {
final JsonWebKey jsonKey = JsonWebKey.fromRsa(keyPair, authorizedOperations).setId(keyId);
return new KeyEncryptionKeyClientBuilder().buildAsyncKeyEncryptionKey(jsonKey).block();
}
}
Expected behavior
It feels like a regression, especially as this behavior differs from the non-encrypted client
Setup (please complete the following information):
- OS:
Linux 6.5.0-44-generic
22.04.1-Ubuntu
- IDE: IntelliJ
- Library/Libraries: bom 1.2.23 to 1.2.24, using
com.azure:azure-storage-blob
andcom.azure:azure-storage-blob-cryptography
- Java version:
Java version: 21.0.3, vendor: Eclipse Adoptium
- App Server/Environment: Local
- Frameworks: None
Information Checklist
Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report
- Bug Description Added
- Repro Steps Added
- Setup information Added
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Metadata
Assignees
Labels
This issue points to a problem in the data-plane of the library.Storage Service (Queues, Blobs, Files)Issues that are reported by GitHub users external to the Azure organization.Workflow: This issue needs attention from Azure service team or SDK teamThe issue doesn't require a change to the product in order to be resolved. Most issues start as that