From d287cf5a9292221db251c987ff3a3ec736a815ac Mon Sep 17 00:00:00 2001 From: Niels Basjes Date: Wed, 7 Dec 2022 19:18:19 +0100 Subject: [PATCH] FileSystemProvider::checkAccess fails on '/' with StorageException (#1065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Make sure to open an issue: https://togithub.com/googleapis/java-storage-nio/issues/1062 - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) Fixes #1062 ☕️ --- .../contrib/nio/CloudStorageFileSystemProvider.java | 5 +++++ .../cloud/storage/contrib/nio/it/ITGcsNio.java | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java b/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java index b2a55fc696..413f11724b 100644 --- a/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java +++ b/google-cloud-nio/src/main/java/com/google/cloud/storage/contrib/nio/CloudStorageFileSystemProvider.java @@ -728,6 +728,11 @@ public void checkAccess(Path path, AccessMode... modes) throws IOException { // Loop will terminate via an exception if all retries are exhausted while (true) { try { + // Edge case is the root directory which triggers the storage.get to throw a + // StorageException. + if (cloudPath.normalize().equals(cloudPath.getRoot())) { + return; + } boolean nullId; if (isNullOrEmpty(userProject)) { nullId = diff --git a/google-cloud-nio/src/test/java/com/google/cloud/storage/contrib/nio/it/ITGcsNio.java b/google-cloud-nio/src/test/java/com/google/cloud/storage/contrib/nio/it/ITGcsNio.java index bd7fd7927a..67126b167d 100644 --- a/google-cloud-nio/src/test/java/com/google/cloud/storage/contrib/nio/it/ITGcsNio.java +++ b/google-cloud-nio/src/test/java/com/google/cloud/storage/contrib/nio/it/ITGcsNio.java @@ -53,6 +53,7 @@ import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; import java.nio.channels.SeekableByteChannel; +import java.nio.file.AccessMode; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileSystem; import java.nio.file.FileVisitResult; @@ -63,6 +64,7 @@ import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.spi.FileSystemProvider; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -1196,6 +1198,16 @@ public void testCopy_replaceFile_withOption_srcDoesNotExist() throws IOException } } + @Test + public void testCheckAccessRoot() throws Exception { + FileSystem fileSystem = getTestBucket(); + Path path = fileSystem.getPath("/"); + FileSystemProvider provider = fileSystem.provider(); + + // Against the real cloud storage this used to throw a StorageException. + provider.checkAccess(path, AccessMode.READ, AccessMode.WRITE); + } + private CloudStorageFileSystem getTestBucket() throws IOException { // in typical usage we use the single-argument version of forBucket // and rely on the user being logged into their project with the