diff --git a/core/arns/src/main/java/software/amazon/awssdk/arns/ArnResource.java b/core/arns/src/main/java/software/amazon/awssdk/arns/ArnResource.java index 6767e6326329..c55a7040148a 100644 --- a/core/arns/src/main/java/software/amazon/awssdk/arns/ArnResource.java +++ b/core/arns/src/main/java/software/amazon/awssdk/arns/ArnResource.java @@ -91,22 +91,22 @@ public static Builder builder() { * @return {@link ArnResource} */ public static ArnResource fromString(String resource) { - Character primarySplitter = StringUtils.findFirstOccurrence(resource, ':', '/'); + Character splitter = StringUtils.findFirstOccurrence(resource, ':', '/'); - if (primarySplitter == null) { - return builder().resource(resource).build(); + if (splitter == null) { + return ArnResource.builder().resource(resource).build(); } - int resourceTypeIndex = resource.indexOf(primarySplitter); - ArnResource.Builder builder = builder().resourceType(resource.substring(0, resourceTypeIndex)); + int resourceTypeColonIndex = resource.indexOf(splitter); - String remainingResource = resource.substring(resourceTypeIndex + 1); - int qualifierColonIndex = remainingResource.lastIndexOf(':'); - if (qualifierColonIndex < 1) { - builder.resource(remainingResource); + ArnResource.Builder builder = ArnResource.builder().resourceType(resource.substring(0, resourceTypeColonIndex)); + int resourceColonIndex = resource.indexOf(splitter, resourceTypeColonIndex); + int qualifierColonIndex = resource.indexOf(splitter, resourceColonIndex + 1); + if (qualifierColonIndex < 0) { + builder.resource(resource.substring(resourceTypeColonIndex + 1)); } else { - builder.resource(remainingResource.substring(0, qualifierColonIndex)); - builder.qualifier(remainingResource.substring(qualifierColonIndex + 1)); + builder.resource(resource.substring(resourceTypeColonIndex + 1, qualifierColonIndex)); + builder.qualifier(resource.substring(qualifierColonIndex + 1)); } return builder.build(); @@ -114,7 +114,11 @@ public static ArnResource fromString(String resource) { @Override public String toString() { - return String.join(":", this.resourceType, this.resource, this.qualifier); + return this.resourceType + + ":" + + this.resource + + ":" + + this.qualifier; } @Override diff --git a/core/arns/src/test/java/software/amazon/awssdk/arns/ArnResourceTest.java b/core/arns/src/test/java/software/amazon/awssdk/arns/ArnResourceTest.java index e47c67329e08..6ec3e4181362 100644 --- a/core/arns/src/test/java/software/amazon/awssdk/arns/ArnResourceTest.java +++ b/core/arns/src/test/java/software/amazon/awssdk/arns/ArnResourceTest.java @@ -15,16 +15,12 @@ package software.amazon.awssdk.arns; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import java.util.Arrays; -import java.util.List; import java.util.Optional; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; public class ArnResourceTest { @@ -68,34 +64,4 @@ public void hashCodeEquals_minimalProperties() { assertThat(arnResource.equals(anotherResource)).isTrue(); assertThat(arnResource.hashCode()).isEqualTo(anotherResource.hashCode()); } - - @ParameterizedTest - @MethodSource("resources") - void arnResource_ParsesCorrectly(String resource, ArnResource expected) { - ArnResource arnResource = ArnResource.fromString(resource); - - assertThat(arnResource.resourceType()).isEqualTo(expected.resourceType()); - assertThat(arnResource.resource()).isEqualTo(expected.resource()); - assertThat(arnResource.qualifier()).isEqualTo(expected.qualifier()); - } - - private static List resources() { - return Arrays.asList( - Arguments.of("myresource", ArnResource.builder().resource("myresource").build()), - Arguments.of("alias/foo/bar", ArnResource.builder().resourceType("alias").resource("foo/bar").build()), - Arguments.of("alias//", ArnResource.builder().resourceType("alias").resource("/").build()), - Arguments.of("alias//a", ArnResource.builder().resourceType("alias").resource("/a").build()), - Arguments.of("alias///a", ArnResource.builder().resourceType("alias").resource("//a").build()), - Arguments.of("alias///a/b", ArnResource.builder().resourceType("alias").resource("//a/b").build()), - Arguments.of("alias/foo", ArnResource.builder().resourceType("alias").resource("foo").build()), - Arguments.of("alias/foo:quali", ArnResource.builder().resourceType("alias").resource("foo").qualifier("quali").build()), - Arguments.of("alias/foo:bar:quali", ArnResource.builder().resourceType("alias").resource("foo:bar").qualifier("quali").build()), - Arguments.of("alias:foo", ArnResource.builder().resourceType("alias").resource("foo").build()), - Arguments.of("alias:foo.bar", ArnResource.builder().resourceType("alias").resource("foo.bar").build()), - Arguments.of("alias:foo/bar", ArnResource.builder().resourceType("alias").resource("foo/bar").build()), - Arguments.of("alias:foo/bar/baz", ArnResource.builder().resourceType("alias").resource("foo/bar/baz").build()), - Arguments.of("alias:foo:quali", ArnResource.builder().resourceType("alias").resource("foo").qualifier("quali").build()), - Arguments.of("alias:foo:bar:quali", ArnResource.builder().resourceType("alias").resource("foo:bar").qualifier("quali").build()) - ); - } } diff --git a/core/arns/src/test/java/software/amazon/awssdk/arns/ArnTest.java b/core/arns/src/test/java/software/amazon/awssdk/arns/ArnTest.java index a7dfb10425cf..1ef33c7d0033 100644 --- a/core/arns/src/test/java/software/amazon/awssdk/arns/ArnTest.java +++ b/core/arns/src/test/java/software/amazon/awssdk/arns/ArnTest.java @@ -31,6 +31,7 @@ public void arnWithBasicResource_ParsesCorrectly() { assertThat(arn.region()).hasValue("us-east-1"); assertThat(arn.accountId()).hasValue("12345678910"); assertThat(arn.resourceAsString()).isEqualTo("myresource"); + System.out.println(arn.resource()); } @Test @@ -64,6 +65,14 @@ public void arnWithResourceTypeAndResource_ParsesCorrectly() { assertThat(arn.service()).isEqualTo("s3"); assertThat(arn.region()).hasValue("us-east-1"); assertThat(arn.resourceAsString()).isEqualTo("bucket:foobar"); + + verifyArnResource(arn.resource()); + } + + private void verifyArnResource(ArnResource arnResource) { + assertThat(arnResource.resource()).isEqualTo("foobar"); + assertThat(arnResource.resourceType()).isPresent(); + assertThat(arnResource.resourceType().get()).isEqualTo("bucket"); } @Test @@ -74,6 +83,12 @@ public void arnWithResourceTypeAndResourceAndQualifier_ParsesCorrectly() { assertThat(arn.service()).isEqualTo("s3"); assertThat(arn.region()).hasValue("us-east-1"); assertThat(arn.resourceAsString()).isEqualTo("bucket:foobar:1"); + + + ArnResource arnResource = arn.resource(); + verifyArnResource(arnResource); + assertThat(arnResource.qualifier()).isPresent(); + assertThat(arnResource.qualifier().get()).isEqualTo("1"); } @Test @@ -84,7 +99,20 @@ public void arnWithResourceTypeAndResource_SlashSplitter_ParsesCorrectly() { assertThat(arn.service()).isEqualTo("s3"); assertThat(arn.region()).hasValue("us-east-1"); assertThat(arn.resourceAsString()).isEqualTo("bucket/foobar"); - } + verifyArnResource(arn.resource()); + } + + @Test + public void arnWithResourceTypeAndResourceAndQualifier_SlashSplitter_ParsesCorrectly() { + String arnString = "arn:aws:s3:us-east-1:12345678910:bucket/foobar/1"; + Arn arn = Arn.fromString(arnString); + assertThat(arn.partition()).isEqualTo("aws"); + assertThat(arn.service()).isEqualTo("s3"); + assertThat(arn.region()).hasValue("us-east-1"); + assertThat(arn.resourceAsString()).isEqualTo("bucket/foobar/1"); + verifyArnResource(arn.resource()); + assertThat(arn.resource().qualifier().get()).isEqualTo("1"); + } @Test public void oneArnEqualsEquivalentArn() { @@ -110,6 +138,30 @@ public void arnFromBuilder_ParsesCorrectly() { assertThat(arn.region()).hasValue("us-east-1"); assertThat(arn.accountId()).hasValue("123456789012"); assertThat(arn.resourceAsString()).isEqualTo("bucket:foobar:1"); + verifyArnResource(arn.resource()); + assertThat(arn.resource().qualifier()).isPresent(); + assertThat(arn.resource().qualifier().get()).isEqualTo("1"); + } + + @Test + public void arnResourceWithColonAndSlash_ParsesOnFirstSplitter() { + String resourceWithColonAndSlash = "object:foobar/myobjectname:1"; + Arn arn = Arn.builder() + .partition("aws") + .service("s3") + .region("us-east-1") + .accountId("123456789012") + .resource(resourceWithColonAndSlash) + .build(); + assertThat(arn.partition()).isEqualTo("aws"); + assertThat(arn.service()).isEqualTo("s3"); + assertThat(arn.region()).hasValue("us-east-1"); + assertThat(arn.accountId()).hasValue("123456789012"); + assertThat(arn.resourceAsString()).isEqualTo(resourceWithColonAndSlash); + + assertThat(arn.resource().resource()).isEqualTo("foobar/myobjectname"); + assertThat(arn.resource().qualifier()).hasValue("1"); + assertThat(arn.resource().resourceType()).hasValue("object"); } @Test @@ -134,6 +186,17 @@ public void arnWithoutAccountId_ParsesCorrectly() { assertThat(arn.resourceAsString()).isEqualTo("myresource"); } + @Test + public void arnResourceContainingDots_ParsesCorrectly() { + String arnString = "arn:aws:s3:us-east-1:12345678910:myresource:foobar.1"; + Arn arn = Arn.fromString(arnString); + assertThat(arn.partition()).isEqualTo("aws"); + assertThat(arn.service()).isEqualTo("s3"); + assertThat(arn.region()).hasValue("us-east-1"); + assertThat(arn.accountId()).hasValue("12345678910"); + assertThat(arn.resourceAsString()).isEqualTo("myresource:foobar.1"); + } + @Test public void toBuilder() { Arn oneArn = Arn.builder() diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/resource/S3ArnUtilsTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/resource/S3ArnUtilsTest.java index 597c3ede5848..b5159aa8bd35 100644 --- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/resource/S3ArnUtilsTest.java +++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/resource/S3ArnUtilsTest.java @@ -122,7 +122,7 @@ public void parseOutpostArn_malformedArnNullSubresource_shouldThrowException() { @Test public void parseOutpostArn_malformedArnEmptyOutpostId_shouldThrowException() { exception.expect(IllegalArgumentException.class); - exception.expectMessage("Invalid format for S3 outpost ARN, missing outpostId"); + exception.expectMessage("resource must not be blank or empty"); S3ArnUtils.parseOutpostArn(Arn.builder() .partition("aws")