Skip to content

Support versionId in S3Utilities#getUrl #2226

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

Merged
merged 1 commit into from
Jan 5, 2021
Merged
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
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