Allow multiple filesystems for a single storage account#48414
Allow multiple filesystems for a single storage account#48414ghostofthecode wants to merge 3 commits intoAzure:mainfrom
Conversation
|
Thank you for your contribution @ghostofthecode! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Pull request overview
This PR updates the azure-storage-blob-nio NIO FileSystemProvider URI handling to allow creating multiple FileSystem instances for the same storage account endpoint by introducing an additional uid query parameter.
Changes:
- Extend the filesystem URI format with an optional
uidquery parameter and update tests to cover distinct UIDs. - Update
AzureFileSystemProviderto parseuidand use it to distinguish cached/open file systems. - Add an (unreleased) changelog entry describing the new URI format.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 8 comments.
| File | Description |
|---|---|
| sdk/storage/azure-storage-blob-nio/src/main/java/com/azure/storage/blob/nio/AzureFileSystemProvider.java | Parses uid from the URI and changes the open-filesystem cache keying strategy. |
| sdk/storage/azure-storage-blob-nio/src/test/java/com/azure/storage/blob/nio/BlobNioTestBase.java | Adds a getFileSystemUri(String uid) helper to generate URIs with a uid. |
| sdk/storage/azure-storage-blob-nio/src/test/java/com/azure/storage/blob/nio/AzureFileSystemProviderTests.java | Adds tests for creating distinct filesystems via different UIDs and updates duplicate-creation coverage. |
| sdk/storage/azure-storage-blob-nio/CHANGELOG.md | Documents the new filesystem URI shape in the Unreleased section. |
Comments suppressed due to low confidence (1)
sdk/storage/azure-storage-blob-nio/src/main/java/com/azure/storage/blob/nio/AzureFileSystemProvider.java:240
newFileSystem()andgetFileSystem()Javadoc still states the URI format isazb://?endpoint=<endpoint>, but this PR introducesuidto distinguish multiple filesystems. Update these docs to reflect the supported format (including whetheruidis optional and what the default behavior is when it’s omitted).
/**
* Constructs a new FileSystem object identified by a URI.
* <p>
* The format of a {@code URI} identifying a file system is {@code "azb://?endpoint=<endpoint>"}.
* <p>
* Once closed, a file system with the same identifier may be reopened.
*
* @param uri URI reference
* @param config A map of provider specific properties to configure the file system
* @return a new file system.
* @throws IllegalArgumentException If the pre-conditions for the uri parameter aren't met, or the env parameter
* does not contain properties required by the provider, or a property value is invalid.
* @throws IOException If an I/O error occurs.
* @throws SecurityException never
* @throws FileSystemAlreadyExistsException If the file system has already been created.
*/
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> config) throws IOException {
FileSystemUriParameters parameters = parseFileSystemParameters(uri);
if (this.openFileSystems.containsKey(parameters.uid())) {
throw LoggingUtility.logError(ClientLoggerHolder.LOGGER,
new FileSystemAlreadyExistsException("Name: " + parameters.endpoint() + " UID: " + parameters.uid()));
}
AzureFileSystem afs = new AzureFileSystem(this, parameters.endpoint(), config);
this.openFileSystems.put(parameters.uid(), afs);
return afs;
}
/**
* Returns an existing FileSystem created by this provider.
* <p>
* The format of a {@code URI} identifying a file system is {@code "azb://?endpoint=<endpoint>"}.
* <p>
* Trying to retrieve a closed file system will throw a {@link FileSystemNotFoundException}. Once closed, a
* file system with the same identifier may be reopened.
*
You can also share your feedback on Copilot code review. Take the survey.
| String endpoint = "", uid = ""; | ||
| for (String queryPart : uri.getQuery().split("&")) { | ||
| String[] parts = queryPart.split("="); | ||
| switch (parts[0]) { | ||
| case ENDPOINT_QUERY_KEY: | ||
| endpoint = parts.length > 1 ? parts[1] : ""; | ||
| break; | ||
|
|
||
| case UID_QUERY_KEY: | ||
| uid = parts.length > 1 ? parts[1] : ""; | ||
| break; | ||
| } | ||
| } | ||
| uid = CoreUtils.isNullOrEmpty(uid) ? endpoint : uid; | ||
|
|
||
| String expectedFormat | ||
| = "FileSystems require a URI of the format \"azb://?endpoint=<endpoint>&uid=<unique_id>\""; | ||
| if (CoreUtils.isNullOrEmpty(uid)) { | ||
| throw LoggingUtility.logError(ClientLoggerHolder.LOGGER, new IllegalArgumentException( | ||
| "URI does not contain an \"" + UID_QUERY_KEY + "=\" parameter. " + expectedFormat)); | ||
| } | ||
| if (CoreUtils.isNullOrEmpty(endpoint)) { | ||
| throw LoggingUtility.logError(ClientLoggerHolder.LOGGER, | ||
| new IllegalArgumentException("No account endpoint provided in URI query.")); | ||
| new IllegalArgumentException("No account endpoint provided in URI query. " + expectedFormat)); |
| for (String queryPart : uri.getQuery().split("&")) { | ||
| String[] parts = queryPart.split("="); | ||
| switch (parts[0]) { | ||
| case ENDPOINT_QUERY_KEY: | ||
| endpoint = parts.length > 1 ? parts[1] : ""; | ||
| break; | ||
|
|
||
| case UID_QUERY_KEY: | ||
| uid = parts.length > 1 ? parts[1] : ""; | ||
| break; |
| ## 12.0.0-beta.37 (Unreleased) | ||
| - Extend azure nio filesystem url to support a unique identifer: `azb://?endpoint=<account_endpoint>&uid=<unique_id>` |
| public FileSystem newFileSystem(URI uri, Map<String, ?> config) throws IOException { | ||
| String endpoint = extractAccountEndpoint(uri); | ||
| FileSystemUriParameters parameters = parseFileSystemParameters(uri); | ||
|
|
||
| if (this.openFileSystems.containsKey(endpoint)) { | ||
| if (this.openFileSystems.containsKey(parameters.uid())) { | ||
| throw LoggingUtility.logError(ClientLoggerHolder.LOGGER, | ||
| new FileSystemAlreadyExistsException("Name: " + endpoint)); | ||
| new FileSystemAlreadyExistsException("Name: " + parameters.endpoint() + " UID: " + parameters.uid())); | ||
| } | ||
|
|
||
| AzureFileSystem afs = new AzureFileSystem(this, endpoint, config); | ||
| this.openFileSystems.put(endpoint, afs); | ||
| AzureFileSystem afs = new AzureFileSystem(this, parameters.endpoint(), config); | ||
| this.openFileSystems.put(parameters.uid(), afs); |
| @ParameterizedTest | ||
| @ValueSource(strings = { "", "test-uid" }) | ||
| public void createFileSystemDuplicate(String uid) throws IOException { | ||
| URI uri = getFileSystemUri(uid == "" ? null : uid); |
| # Release History | ||
|
|
||
| ## 12.0.0-beta.37 (Unreleased) | ||
| - Extend azure nio filesystem url to support a unique identifer: `azb://?endpoint=<account_endpoint>&uid=<unique_id>` |
| void closeFileSystem(String fileSystemName) { | ||
| this.openFileSystems.remove(fileSystemName); | ||
| } | ||
|
|
||
| private String extractAccountEndpoint(URI uri) { | ||
| /** |
|
@alzimmermsft, @browndav-msft, @browndav-msft, @gunjansingh-msft, @ibrandes, @kyleknap the proposed test changes involve amendments to |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Description
Please add an informative description that covers that changes made by the pull request and link all relevant issues.
If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.
All SDK Contribution checklist:
General Guidelines and Best Practices
Testing Guidelines