Skip to content

Commit 514f663

Browse files
adoroszlaiechonesis
authored andcommitted
HDDS-14221. Support primitive query params (apache#9537)
1 parent b8953ec commit 514f663

7 files changed

Lines changed: 209 additions & 130 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.hadoop.ozone.s3.commontypes;
19+
20+
import javax.ws.rs.WebApplicationException;
21+
import javax.ws.rs.core.MultivaluedMap;
22+
import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
23+
24+
/** Allow looking up query parameters as primitive types. */
25+
public interface RequestParameters {
26+
27+
String get(String key);
28+
29+
static MultivaluedMapImpl of(MultivaluedMap<String, String> params) {
30+
return new MultivaluedMapImpl(params);
31+
}
32+
33+
default String get(String key, String defaultValue) {
34+
final String value = get(key);
35+
return value != null ? value : defaultValue;
36+
}
37+
38+
default int getInt(String key, int defaultValue) {
39+
final String value = get(key);
40+
if (value == null) {
41+
return defaultValue;
42+
}
43+
44+
try {
45+
return Integer.parseInt(value);
46+
} catch (NumberFormatException e) {
47+
throw translateException(e);
48+
}
49+
}
50+
51+
default WebApplicationException translateException(RuntimeException e) {
52+
return new WebApplicationException(e.getMessage(), S3ErrorTable.INVALID_ARGUMENT.getHttpCode());
53+
}
54+
55+
/** Additional methods for tests. */
56+
interface Mutable extends RequestParameters {
57+
58+
void set(String key, String value);
59+
60+
void unset(String key);
61+
62+
default void setInt(String key, int value) {
63+
set(key, String.valueOf(value));
64+
}
65+
}
66+
67+
/** Mutable implementation based on {@link MultivaluedMap}. */
68+
final class MultivaluedMapImpl implements Mutable {
69+
private final MultivaluedMap<String, String> params;
70+
71+
private MultivaluedMapImpl(MultivaluedMap<String, String> params) {
72+
this.params = params;
73+
}
74+
75+
@Override
76+
public String get(String key) {
77+
return params.getFirst(key);
78+
}
79+
80+
@Override
81+
public void set(String key, String value) {
82+
params.putSingle(key, value);
83+
}
84+
85+
@Override
86+
public void unset(String key) {
87+
params.remove(key);
88+
}
89+
}
90+
}

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import java.util.Set;
4141
import javax.annotation.PostConstruct;
4242
import javax.ws.rs.DELETE;
43-
import javax.ws.rs.DefaultValue;
4443
import javax.ws.rs.GET;
4544
import javax.ws.rs.HEAD;
4645
import javax.ws.rs.POST;
@@ -116,28 +115,28 @@ private BucketEndpointContext getBucketContext() {
116115
@GET
117116
@SuppressWarnings("methodlength")
118117
public Response get(
119-
@PathParam(BUCKET) String bucketName,
120-
@DefaultValue("1000") @QueryParam(QueryParams.MAX_KEYS) int maxKeys,
121-
@DefaultValue("1000") @QueryParam(QueryParams.MAX_UPLOADS) int maxUploads
118+
@PathParam(BUCKET) String bucketName
122119
) throws OS3Exception, IOException {
123120
long startNanos = Time.monotonicNowNanos();
124121
S3GAction s3GAction = S3GAction.GET_BUCKET;
125122
PerformanceStringBuilder perf = new PerformanceStringBuilder();
126123

127-
final String continueToken = getQueryParam(QueryParams.CONTINUATION_TOKEN);
128-
final String delimiter = getQueryParam(QueryParams.DELIMITER);
129-
final String encodingType = getQueryParam(QueryParams.ENCODING_TYPE);
130-
final String marker = getQueryParam(QueryParams.MARKER);
131-
String prefix = getQueryParam(QueryParams.PREFIX);
132-
String startAfter = getQueryParam(QueryParams.START_AFTER);
124+
final String continueToken = queryParams().get(QueryParams.CONTINUATION_TOKEN);
125+
final String delimiter = queryParams().get(QueryParams.DELIMITER);
126+
final String encodingType = queryParams().get(QueryParams.ENCODING_TYPE);
127+
final String marker = queryParams().get(QueryParams.MARKER);
128+
int maxKeys = queryParams().getInt(QueryParams.MAX_KEYS, 1000);
129+
final int maxUploads = queryParams().getInt(QueryParams.MAX_UPLOADS, 1000);
130+
String prefix = queryParams().get(QueryParams.PREFIX);
131+
String startAfter = queryParams().get(QueryParams.START_AFTER);
133132

134133
Iterator<? extends OzoneKey> ozoneKeyIterator = null;
135134
ContinueToken decodedToken =
136135
ContinueToken.decodeFromString(continueToken);
137136
OzoneBucket bucket = null;
138137

139138
try {
140-
final String aclMarker = getQueryParam(QueryParams.ACL);
139+
final String aclMarker = queryParams().get(QueryParams.ACL);
141140
if (aclMarker != null) {
142141
s3GAction = S3GAction.GET_ACL;
143142
S3BucketAcl result = getAcl(bucketName);
@@ -146,11 +145,11 @@ public Response get(
146145
return Response.ok(result, MediaType.APPLICATION_XML_TYPE).build();
147146
}
148147

149-
final String uploads = getQueryParam(QueryParams.UPLOADS);
148+
final String uploads = queryParams().get(QueryParams.UPLOADS);
150149
if (uploads != null) {
151150
s3GAction = S3GAction.LIST_MULTIPART_UPLOAD;
152-
final String uploadIdMarker = getQueryParam(QueryParams.UPLOAD_ID_MARKER);
153-
final String keyMarker = getQueryParam(QueryParams.KEY_MARKER);
151+
final String uploadIdMarker = queryParams().get(QueryParams.UPLOAD_ID_MARKER);
152+
final String keyMarker = queryParams().get(QueryParams.KEY_MARKER);
154153
return listMultipartUploads(bucketName, prefix, keyMarker, uploadIdMarker, maxUploads);
155154
}
156155

@@ -324,7 +323,7 @@ public Response put(
324323
S3GAction s3GAction = S3GAction.CREATE_BUCKET;
325324

326325
try {
327-
final String aclMarker = getQueryParam(QueryParams.ACL);
326+
final String aclMarker = queryParams().get(QueryParams.ACL);
328327
if (aclMarker != null) {
329328
s3GAction = S3GAction.PUT_ACL;
330329
Response response = putAcl(bucketName, body);

hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes;
7070
import org.apache.hadoop.ozone.om.protocol.S3Auth;
7171
import org.apache.hadoop.ozone.s3.RequestIdentifier;
72+
import org.apache.hadoop.ozone.s3.commontypes.RequestParameters;
7273
import org.apache.hadoop.ozone.s3.exception.OS3Exception;
7374
import org.apache.hadoop.ozone.s3.exception.S3ErrorTable;
7475
import org.apache.hadoop.ozone.s3.metrics.S3GatewayMetrics;
@@ -106,6 +107,9 @@ public abstract class EndpointBase {
106107
@Context
107108
private HttpHeaders headers;
108109

110+
// initialized in @PostConstruct
111+
private RequestParameters.MultivaluedMapImpl queryParams;
112+
109113
private final Set<String> excludeMetadataFields =
110114
new HashSet<>(Arrays.asList(OzoneConsts.GDPR_FLAG, STORAGE_CONFIG_HEADER));
111115
private static final Logger LOG =
@@ -114,12 +118,14 @@ public abstract class EndpointBase {
114118
protected static final AuditLogger AUDIT =
115119
new AuditLogger(AuditLoggerType.S3GLOGGER);
116120

117-
protected String getQueryParam(String key) {
118-
return getQueryParameters().getFirst(key);
121+
/** Read-only access to query parameters. */
122+
protected RequestParameters queryParams() {
123+
return queryParams;
119124
}
120125

121-
public MultivaluedMap<String, String> getQueryParameters() {
122-
return context.getUriInfo().getQueryParameters();
126+
/** For setting multiple values use {@link #getContext()}. */
127+
public RequestParameters.Mutable queryParamsForTest() {
128+
return queryParams;
123129
}
124130

125131
protected OzoneBucket getBucket(OzoneVolume volume, String bucketName)
@@ -149,6 +155,7 @@ protected OzoneBucket getBucket(OzoneVolume volume, String bucketName)
149155
*/
150156
@PostConstruct
151157
public void initialization() {
158+
queryParams = RequestParameters.of(context.getUriInfo().getQueryParameters());
152159
// Note: userPrincipal is initialized to be the same value as accessId,
153160
// could be updated later in RpcClient#getS3Volume
154161
s3Auth = new S3Auth(signatureInfo.getStringToSign(),

hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3/endpoint/TestBucketAcl.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public void setup() throws IOException {
6969
.setClient(client)
7070
.setHeaders(headers)
7171
.build();
72-
bucketEndpoint.getQueryParameters().add(QueryParams.ACL, ACL_MARKER);
72+
bucketEndpoint.queryParamsForTest().set(QueryParams.ACL, ACL_MARKER);
7373
}
7474

7575
@AfterEach
@@ -82,8 +82,7 @@ public void clean() throws IOException {
8282
@Test
8383
public void testGetAcl() throws Exception {
8484
when(parameterMap.containsKey(ACL_MARKER)).thenReturn(true);
85-
Response response =
86-
bucketEndpoint.get(BUCKET_NAME, 0, 0);
85+
Response response = bucketEndpoint.get(BUCKET_NAME);
8786
assertEquals(HTTP_OK, response.getStatus());
8887
System.out.println(response.getEntity());
8988
}

0 commit comments

Comments
 (0)