Skip to content

Commit 27dca5d

Browse files
committed
Support versionId in S3Utilities#getUrl
1 parent 84ba31e commit 27dca5d

File tree

4 files changed

+74
-9
lines changed

4 files changed

+74
-9
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "Amazon S3",
3+
"contributor": "",
4+
"type": "feature",
5+
"description": "`S3Utilities#getUrl` now supports versionId. See [#2224](https://github.com/aws/aws-sdk-java-v2/issues/2224)"
6+
}

services/s3/src/main/java/software/amazon/awssdk/services/s3/S3Utilities.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static S3Utilities create(SdkClientConfiguration clientConfiguration) {
124124
*
125125
* @param getUrlRequest A {@link Consumer} that will call methods on {@link GetUrlRequest.Builder} to create a request.
126126
* @return A URL for an object stored in Amazon S3.
127-
* @throws MalformedURLException Generated Url is malformed
127+
* @throws SdkException Generated Url is malformed
128128
*/
129129
public URL getUrl(Consumer<GetUrlRequest.Builder> getUrlRequest) {
130130
return getUrl(GetUrlRequest.builder().applyMutation(getUrlRequest).build());
@@ -143,7 +143,7 @@ public URL getUrl(Consumer<GetUrlRequest.Builder> getUrlRequest) {
143143
*
144144
* @param getUrlRequest request to construct url
145145
* @return A URL for an object stored in Amazon S3.
146-
* @throws MalformedURLException Generated Url is malformed
146+
* @throws SdkException Generated Url is malformed
147147
*/
148148
public URL getUrl(GetUrlRequest getUrlRequest) {
149149
Region resolvedRegion = resolveRegionForGetUrl(getUrlRequest);
@@ -155,6 +155,7 @@ public URL getUrl(GetUrlRequest getUrlRequest) {
155155
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
156156
.bucket(getUrlRequest.bucket())
157157
.key(getUrlRequest.key())
158+
.versionId(getUrlRequest.versionId())
158159
.build();
159160

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

219+
if (getUrlRequest.versionId() != null) {
220+
builder.appendRawQueryParameter("versionId", getUrlRequest.versionId());
221+
}
222+
218223
return builder.build();
219224
}
220225

@@ -258,19 +263,19 @@ public Builder s3Configuration(S3Configuration s3Configuration) {
258263
}
259264

260265
/**
261-
* The profile file from the {@link ClientOverrideConfiguration#profileFile()}. This is private and only used when the
262-
* utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less confusing
263-
* to support the full {@link ClientOverrideConfiguration} object in the future.
266+
* The profile file from the {@link ClientOverrideConfiguration#defaultProfileFile()}. This is private and only used
267+
* when the utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less
268+
* confusing to support the full {@link ClientOverrideConfiguration} object in the future.
264269
*/
265270
private Builder profileFile(ProfileFile profileFile) {
266271
this.profileFile = profileFile;
267272
return this;
268273
}
269274

270275
/**
271-
* The profile name from the {@link ClientOverrideConfiguration#profileName()}. This is private and only used when the
272-
* utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less confusing
273-
* to support the full {@link ClientOverrideConfiguration} object in the future.
276+
* The profile name from the {@link ClientOverrideConfiguration#defaultProfileFile()}. This is private and only used
277+
* when the utilities is created via {@link S3Client#utilities()}. This is not currently public because it may be less
278+
* confusing to support the full {@link ClientOverrideConfiguration} object in the future.
274279
*/
275280
private Builder profileName(String profileName) {
276281
this.profileName = profileName;

services/s3/src/main/java/software/amazon/awssdk/services/s3/model/GetUrlRequest.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ public final class GetUrlRequest implements SdkPojo, ToCopyableBuilder<GetUrlReq
5555
.traits(LocationTrait.builder().location(MarshallLocation.GREEDY_PATH).locationName("Key")
5656
.unmarshallLocationName("Key").build()).build();
5757

58-
private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(BUCKET_FIELD, KEY_FIELD));
58+
private static final SdkField<String> VERSION_ID_FIELD = SdkField
59+
.builder(MarshallingType.STRING)
60+
.memberName("VersionId")
61+
.getter(getter(GetUrlRequest::versionId))
62+
.setter(setter(Builder::versionId))
63+
.traits(LocationTrait.builder().location(MarshallLocation.QUERY_PARAM).locationName("versionId")
64+
.unmarshallLocationName("versionId").build()).build();
65+
66+
private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList(BUCKET_FIELD, KEY_FIELD,
67+
VERSION_ID_FIELD));
5968

6069
private final String bucket;
6170

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

6675
private final URI endpoint;
6776

77+
private final String versionId;
78+
6879
private GetUrlRequest(BuilderImpl builder) {
6980
this.bucket = Validate.paramNotBlank(builder.bucket, "Bucket");
7081
this.key = Validate.paramNotBlank(builder.key, "Key");
7182
this.region = builder.region;
7283
this.endpoint = builder.endpoint;
84+
this.versionId = builder.versionId;
7385
}
7486

7587
/**
@@ -100,6 +112,15 @@ public URI endpoint() {
100112
return endpoint;
101113
}
102114

115+
/**
116+
* VersionId used to reference a specific version of the object.
117+
*
118+
* @return VersionId used to reference a specific version of the object.
119+
*/
120+
public String versionId() {
121+
return versionId;
122+
}
123+
103124
@Override
104125
public Builder toBuilder() {
105126
return new BuilderImpl(this);
@@ -115,6 +136,8 @@ public <T> Optional<T> getValueForField(String fieldName, Class<T> clazz) {
115136
return Optional.ofNullable(clazz.cast(bucket()));
116137
case "Key":
117138
return Optional.ofNullable(clazz.cast(key()));
139+
case "VersionId":
140+
return Optional.ofNullable(clazz.cast(versionId()));
118141
default:
119142
return Optional.empty();
120143
}
@@ -152,6 +175,15 @@ public interface Builder extends SdkPojo, CopyableBuilder<Builder, GetUrlRequest
152175
*/
153176
Builder key(String key);
154177

178+
/**
179+
* VersionId used to reference a specific version of the object.
180+
*
181+
* @param versionId
182+
* VersionId used to reference a specific version of the object.
183+
* @return Returns a reference to this object so that method calls can be chained together.
184+
*/
185+
Builder versionId(String versionId);
186+
155187
/**
156188
* Sets the region to use for constructing the URL.
157189
*
@@ -181,6 +213,8 @@ private static final class BuilderImpl implements Builder {
181213

182214
private URI endpoint;
183215

216+
private String versionId;
217+
184218
private BuilderImpl() {
185219
}
186220

@@ -203,6 +237,12 @@ public Builder key(String key) {
203237
return this;
204238
}
205239

240+
@Override
241+
public Builder versionId(String versionId) {
242+
this.versionId = versionId;
243+
return this;
244+
}
245+
206246
@Override
207247
public Builder region(Region region) {
208248
this.region = region;

services/s3/src/test/java/software/amazon/awssdk/services/s3/S3UtilitiesTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.net.MalformedURLException;
2121
import java.net.URI;
22+
import java.net.URL;
2223
import org.junit.AfterClass;
2324
import org.junit.BeforeClass;
2425
import org.junit.Test;
@@ -159,6 +160,19 @@ public void failIfRegionIsNotSetOnS3UtilitiesObject() throws MalformedURLExcepti
159160
S3Utilities.builder().build();
160161
}
161162

163+
@Test
164+
public void getUrlWithVersionId() {
165+
S3Utilities utilities = S3Utilities.builder().region(Region.US_WEST_2).build();
166+
167+
assertThat(utilities.getUrl(b -> b.bucket("foo").key("bar").versionId("1"))
168+
.toExternalForm())
169+
.isEqualTo("https://foo.s3.us-west-2.amazonaws.com/bar?versionId=1");
170+
171+
assertThat(utilities.getUrl(b -> b.bucket("foo").key("bar").versionId("@1"))
172+
.toExternalForm())
173+
.isEqualTo("https://foo.s3.us-west-2.amazonaws.com/bar?versionId=%401");
174+
}
175+
162176
private static GetUrlRequest requestWithoutSpaces() {
163177
return GetUrlRequest.builder()
164178
.bucket("foo-bucket")

0 commit comments

Comments
 (0)