Skip to content

Commit

Permalink
Support versionId in S3Utilities#getUrl
Browse files Browse the repository at this point in the history
  • Loading branch information
zoewangg committed Jan 5, 2021
1 parent 84ba31e commit 27dca5d
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 9 deletions.
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AmazonS3-deae2cc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"category": "Amazon S3",
"contributor": "",
"type": "feature",
"description": "`S3Utilities#getUrl` now supports versionId. See [#2224](https://github.com/aws/aws-sdk-java-v2/issues/2224)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static S3Utilities create(SdkClientConfiguration clientConfiguration) {
*
* @param getUrlRequest A {@link Consumer} that will call methods on {@link GetUrlRequest.Builder} to create a request.
* @return A URL for an object stored in Amazon S3.
* @throws MalformedURLException Generated Url is malformed
* @throws SdkException Generated Url is malformed
*/
public URL getUrl(Consumer<GetUrlRequest.Builder> getUrlRequest) {
return getUrl(GetUrlRequest.builder().applyMutation(getUrlRequest).build());
Expand All @@ -143,7 +143,7 @@ public URL getUrl(Consumer<GetUrlRequest.Builder> getUrlRequest) {
*
* @param getUrlRequest request to construct url
* @return A URL for an object stored in Amazon S3.
* @throws MalformedURLException Generated Url is malformed
* @throws SdkException Generated Url is malformed
*/
public URL getUrl(GetUrlRequest getUrlRequest) {
Region resolvedRegion = resolveRegionForGetUrl(getUrlRequest);
Expand All @@ -155,6 +155,7 @@ public URL getUrl(GetUrlRequest getUrlRequest) {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(getUrlRequest.bucket())
.key(getUrlRequest.key())
.versionId(getUrlRequest.versionId())
.build();

S3EndpointResolverContext resolverContext = S3EndpointResolverContext.builder()
Expand Down Expand Up @@ -215,6 +216,10 @@ private SdkHttpFullRequest createMarshalledRequest(GetUrlRequest getUrlRequest,
// encode key
builder.encodedPath(PathMarshaller.GREEDY.marshall(builder.encodedPath(), "Key", getUrlRequest.key()));

if (getUrlRequest.versionId() != null) {
builder.appendRawQueryParameter("versionId", getUrlRequest.versionId());
}

return builder.build();
}

Expand Down Expand Up @@ -258,19 +263,19 @@ public Builder s3Configuration(S3Configuration s3Configuration) {
}

/**
* The profile file from the {@link ClientOverrideConfiguration#profileFile()}. This is private and only used when the
* utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less confusing
* to support the full {@link ClientOverrideConfiguration} object in the future.
* The profile file from the {@link ClientOverrideConfiguration#defaultProfileFile()}. This is private and only used
* when the utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less
* confusing to support the full {@link ClientOverrideConfiguration} object in the future.
*/
private Builder profileFile(ProfileFile profileFile) {
this.profileFile = profileFile;
return this;
}

/**
* The profile name from the {@link ClientOverrideConfiguration#profileName()}. This is private and only used when the
* utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less confusing
* to support the full {@link ClientOverrideConfiguration} object in the future.
* The profile name from the {@link ClientOverrideConfiguration#defaultProfileFile()}. This is private and only used
* when the utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less
* confusing to support the full {@link ClientOverrideConfiguration} object in the future.
*/
private Builder profileName(String profileName) {
this.profileName = profileName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,16 @@ public final class GetUrlRequest implements SdkPojo, ToCopyableBuilder<GetUrlReq
.traits(LocationTrait.builder().location(MarshallLocation.GREEDY_PATH).locationName("Key")
.unmarshallLocationName("Key").build()).build();

private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(BUCKET_FIELD, KEY_FIELD));
private static final SdkField<String> VERSION_ID_FIELD = SdkField
.builder(MarshallingType.STRING)
.memberName("VersionId")
.getter(getter(GetUrlRequest::versionId))
.setter(setter(Builder::versionId))
.traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("versionId")
.unmarshallLocationName("versionId").build()).build();

private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(BUCKET_FIELD, KEY_FIELD,
VERSION_ID_FIELD));

private final String bucket;

Expand All @@ -65,11 +74,14 @@ public final class GetUrlRequest implements SdkPojo, ToCopyableBuilder<GetUrlReq

private final URI endpoint;

private final String versionId;

private GetUrlRequest(BuilderImpl builder) {
this.bucket = Validate.paramNotBlank(builder.bucket, "Bucket");
this.key = Validate.paramNotBlank(builder.key, "Key");
this.region = builder.region;
this.endpoint = builder.endpoint;
this.versionId = builder.versionId;
}

/**
Expand Down Expand Up @@ -100,6 +112,15 @@ public URI endpoint() {
return endpoint;
}

/**
* VersionId used to reference a specific version of the object.
*
* @return VersionId used to reference a specific version of the object.
*/
public String versionId() {
return versionId;
}

@Override
public Builder toBuilder() {
return new BuilderImpl(this);
Expand All @@ -115,6 +136,8 @@ public <T> Optional<T> getValueForField(String fieldName, Class<T> clazz) {
return Optional.ofNullable(clazz.cast(bucket()));
case "Key":
return Optional.ofNullable(clazz.cast(key()));
case "VersionId":
return Optional.ofNullable(clazz.cast(versionId()));
default:
return Optional.empty();
}
Expand Down Expand Up @@ -152,6 +175,15 @@ public interface Builder extends SdkPojo, CopyableBuilder<Builder, GetUrlRequest
*/
Builder key(String key);

/**
* VersionId used to reference a specific version of the object.
*
* @param versionId
* VersionId used to reference a specific version of the object.
* @return Returns a reference to this object so that method calls can be chained together.
*/
Builder versionId(String versionId);

/**
* Sets the region to use for constructing the URL.
*
Expand Down Expand Up @@ -181,6 +213,8 @@ private static final class BuilderImpl implements Builder {

private URI endpoint;

private String versionId;

private BuilderImpl() {
}

Expand All @@ -203,6 +237,12 @@ public Builder key(String key) {
return this;
}

@Override
public Builder versionId(String versionId) {
this.versionId = versionId;
return this;
}

@Override
public Builder region(Region region) {
this.region = region;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
Expand Down Expand Up @@ -159,6 +160,19 @@ public void failIfRegionIsNotSetOnS3UtilitiesObject() throws MalformedURLExcepti
S3Utilities.builder().build();
}

@Test
public void getUrlWithVersionId() {
S3Utilities utilities = S3Utilities.builder().region(Region.US_WEST_2).build();

assertThat(utilities.getUrl(b -> b.bucket("foo").key("bar").versionId("1"))
.toExternalForm())
.isEqualTo("https://foo.s3.us-west-2.amazonaws.com/bar?versionId=1");

assertThat(utilities.getUrl(b -> b.bucket("foo").key("bar").versionId("@1"))
.toExternalForm())
.isEqualTo("https://foo.s3.us-west-2.amazonaws.com/bar?versionId=%401");
}

private static GetUrlRequest requestWithoutSpaces() {
return GetUrlRequest.builder()
.bucket("foo-bucket")
Expand Down

0 comments on commit 27dca5d

Please sign in to comment.