diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/fs/ResourceId.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/fs/ResourceId.java
index 1707016b050b9..d607e4a06ebe0 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/io/fs/ResourceId.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/io/fs/ResourceId.java
@@ -46,6 +46,19 @@ public interface ResourceId {
* This {@code ResourceId} should represents a directory.
*
*
It is up to each file system to resolve in their own way.
+ *
+ *
Resolving special characters:
+ *
+ * - {@code resourceId.resolve("..", StandardResolveOptions.RESOLVE_DIRECTORY)} returns
+ * the parent directory of this {@code ResourceId}.
+ *
- {@code resourceId.resolve("{@literal *}", StandardResolveOptions.RESOLVE_FILE)} returns
+ * a {@code ResourceId} which matches all files in this {@code ResourceId}.
+ *
- {@code resourceId.resolve("{@literal *}", StandardResolveOptions.RESOLVE_DIRECTORY)}
+ * returns a {@code ResourceId} which matches all directories in this {@code ResourceId}.
+ *
+ *
+ * @throws IllegalArgumentException if other contains illegal characters or is an illegal name.
+ * It is recommended that callers use common characters, such as [_a-zA-Z0-9-], in {@code other}.
*/
ResourceId resolve(String other, ResolveOptions resolveOptions);
diff --git a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/gcsfs/GcsPath.java b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/gcsfs/GcsPath.java
index 8ab42169baee4..863b01b8b83aa 100644
--- a/sdks/java/core/src/main/java/org/apache/beam/sdk/util/gcsfs/GcsPath.java
+++ b/sdks/java/core/src/main/java/org/apache/beam/sdk/util/gcsfs/GcsPath.java
@@ -440,7 +440,7 @@ public Path resolveSibling(Path other) {
}
@Override
- public GcsPath resolveSibling(String other) {
+ public Path resolveSibling(String other) {
if (getNameCount() < 2) {
throw new UnsupportedOperationException("Can't resolve the sibling of a root path: " + this);
}
diff --git a/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/storage/GcsResourceIdTest.java b/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/storage/GcsResourceIdTest.java
index 40a0b82debc96..ee76ca5fc615a 100644
--- a/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/storage/GcsResourceIdTest.java
+++ b/sdks/java/io/google-cloud-platform/src/test/java/org/apache/beam/sdk/io/gcp/storage/GcsResourceIdTest.java
@@ -76,8 +76,7 @@ public void testResolveHandleBadInputs() throws Exception {
@Test
public void testResolveInvalidInputs() throws Exception {
thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage(
- "The resolved file: [tmp/] should not end with '/'.");
+ thrown.expectMessage("The resolved file: [tmp/] should not end with '/'.");
toResourceIdentifier("gs://my_bucket/").resolve("tmp/", StandardResolveOptions.RESOLVE_FILE);
}
@@ -93,15 +92,27 @@ public void testResolveInvalidNotDirectory() throws Exception {
@Test
public void testGetCurrentDirectory() throws Exception {
- // Tests for local files without the scheme.
+ // Tests gcs paths.
assertEquals(
toResourceIdentifier("gs://my_bucket/tmp dir/"),
toResourceIdentifier("gs://my_bucket/tmp dir/").getCurrentDirectory());
- // Tests path with unicode
+ // Tests path with unicode.
assertEquals(
toResourceIdentifier("gs://my_bucket/输出 目录/"),
toResourceIdentifier("gs://my_bucket/输出 目录/文件01.txt").getCurrentDirectory());
+
+ // Tests bucket with no ending '/'.
+ assertEquals(
+ toResourceIdentifier("gs://my_bucket/"),
+ toResourceIdentifier("gs://my_bucket").getCurrentDirectory());
+ }
+
+ @Test
+ public void testInvalidGcsPath() throws Exception {
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("Invalid GCS URI: gs://");
+ toResourceIdentifier("gs://");
}
@Test