Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More robust s3 path resolve #378

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions src/main/java/org/carlspring/cloud/storage/s3fs/S3Path.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class S3Path

public static final String PATH_SEPARATOR = "/";
public static final String PATH_OTHER_INSTANCE_MESSAGE = "other must be an instance of %s";
public static final String PATH_OTHER_INSTANCE_OR_RELATIVE_MESSAGE = "other must be an instance of %s or a relative Path";

/**
* S3FileStore which represents the Bucket this path resides in.
Expand Down Expand Up @@ -444,16 +445,34 @@ public Path normalize()
@Override
public Path resolve(Path other)
{
String otherUri = "";
if (other.isAbsolute())
{
Preconditions.checkArgument(other instanceof S3Path,
PATH_OTHER_INSTANCE_MESSAGE,
PATH_OTHER_INSTANCE_OR_RELATIVE_MESSAGE,
S3Path.class.getName());

return other;
}
else if (other instanceof S3Path)
{
S3Path otherS3Path = (S3Path) other;
otherUri = otherS3Path.uri;
}
else
{
int nameCount = other.getNameCount();
for (int i = 0; i < nameCount; i++)
{
if (i > 0)
{
otherUri += PATH_SEPARATOR;
}

otherUri += other.getName(i);
}
}

S3Path otherS3Path = (S3Path) other;
StringBuilder pathBuilder = new StringBuilder();

if (this.isAbsolute())
Expand All @@ -463,9 +482,9 @@ public Path resolve(Path other)

pathBuilder.append(this.uri);

if (!otherS3Path.uri.isEmpty())
if (!otherUri.isEmpty())
{
pathBuilder.append(PATH_SEPARATOR + otherS3Path.uri);
pathBuilder.append(PATH_SEPARATOR + otherUri);
}

return new S3Path(this.fileSystem, pathBuilder.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import org.carlspring.cloud.storage.s3fs.util.S3EndpointConstant;

import java.io.IOException;
import java.nio.file.Paths;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.carlspring.cloud.storage.s3fs.util.S3EndpointConstant.S3_GLOBAL_URI_TEST;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

class ResolveTest
extends S3UnitTestBase
Expand Down Expand Up @@ -64,4 +66,34 @@ void resolve()
assertEquals(getPath("/bucket2/other/child"), getPath("/bucket/path/to/file").resolve("/bucket2/other/child"));
}


@Test
void nonS3Paths()
{
S3Path parent = getPath("/bucket");
S3Path child = getPath("/bucket/rabbit");
S3Path deepChild = getPath("/bucket/rabbit/in/space");
S3Path resolved = (S3Path) parent.resolve(child);

assertEquals(child, resolved);

resolved = (S3Path) parent.resolve("rabbit");
assertEquals(child, resolved);

resolved = (S3Path) parent.resolve(Paths.get("rabbit")); //unixPath
assertEquals(child, resolved);

resolved = (S3Path) parent.resolve(Paths.get("rabbit").resolve("in").resolve("space"));
assertEquals(deepChild, resolved);

resolved = (S3Path) parent.resolve(Paths.get("./rabbit")); //unixPath
assertEquals("s3://s3.test.amazonaws.com/bucket/./rabbit", resolved.toString());

resolved = (S3Path) parent.resolve(Paths.get("./rabbit in space")); //unixPath
assertEquals("s3://s3.test.amazonaws.com/bucket/./rabbit%20in%20space", resolved.toString());

IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () ->
parent.resolve(Paths.get("tempDirectory").toAbsolutePath()));
assertEquals("other must be an instance of org.carlspring.cloud.storage.s3fs.S3Path or a relative Path", e.getMessage());
}
}