Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,20 @@ default void setInt(String key, int value) {
}
}

default boolean getBoolean(String key, boolean defaultValue) {
final String value = get(key);
if (value == null) {
return defaultValue;
}
if ("true".equalsIgnoreCase(value)) {
return true;
}
if ("false".equalsIgnoreCase(value)) {
return false;
}
throw S3ErrorTable.newError(S3ErrorTable.INVALID_ARGUMENT, key);
}

/** Mutable implementation based on {@link MultivaluedMap}. */
final class MultivaluedMapImpl implements Mutable {
private final MultivaluedMap<String, String> params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Response handleGetRequest(S3RequestContext context, String bucketName) throws IO
int maxKeys = queryParams().getInt(QueryParams.MAX_KEYS, 1000);
String prefix = queryParams().get(QueryParams.PREFIX, "");
String startAfter = queryParams().get(QueryParams.START_AFTER);

boolean includeOwner = shouldIncludeOwnerInListResponse();
Iterator<? extends OzoneKey> ozoneKeyIterator = null;
// AWS S3 treats an empty continuation-token as no token: list from the
// start and echo the empty token back (see setContinueToken below).
Expand Down Expand Up @@ -217,11 +217,11 @@ Response handleGetRequest(S3RequestContext context, String bucketName) throws IO
} else {
// means our key is matched with prefix if prefix is given and it
// does not have any common prefix.
addKey(response, next);
addKey(response, next, includeOwner);
count++;
}
} else {
addKey(response, next);
addKey(response, next, includeOwner);
count++;
}

Expand Down Expand Up @@ -402,7 +402,7 @@ public MultiDeleteResponse multiDelete(
return result;
}

private void addKey(ListObjectResponse response, OzoneKey next) {
private void addKey(ListObjectResponse response, OzoneKey next, boolean includeOwner) {
KeyMetadata keyMetadata = new KeyMetadata();
keyMetadata.setKey(EncodingTypeObject.createNullable(next.getName(),
response.getEncodingType()));
Expand All @@ -414,8 +414,9 @@ private void addKey(ListObjectResponse response, OzoneKey next) {
keyMetadata.setStorageClass(S3StorageType.fromReplicationConfig(
next.getReplicationConfig()).toString());
keyMetadata.setLastModified(next.getModificationTime());
String displayName = next.getOwner();
keyMetadata.setOwner(S3Owner.of(displayName));
if (includeOwner) {
keyMetadata.setOwner(S3Owner.of(next.getOwner()));
}
response.addKey(keyMetadata);
}

Expand All @@ -439,4 +440,10 @@ protected void init() {
.build();
handler = new AuditingBucketOperationHandler(chain);
}

private boolean shouldIncludeOwnerInListResponse() {
int listType = queryParams().getInt(QueryParams.LIST_TYPE, 1);
boolean fetchOwner = queryParams().getBoolean(QueryParams.FETCH_OWNER, false);
return listType != 2 || fetchOwner;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ public static final class QueryParams {
public static final String DELIMITER = "delimiter";
public static final String ENCODING_TYPE = "encoding-type";
public static final String KEY_MARKER = "key-marker";
public static final String FETCH_OWNER = "fetch-owner";
public static final String LIST_TYPE = "list-type";
// GetBucketLocation is not implemented
public static final String LOCATION = "location";
public static final String MARKER = "marker";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,43 @@ public void continuationTokenXmlElementName() throws Exception {
"response must not use the non-AWS <continueToken> element");
}

@Test
public void listObjectOwnerOmittedForListV2ByDefault() throws OS3Exception, IOException {
OzoneClient client = createClientWithKeys("key1", "key2");
BucketEndpoint endpoint = newBucketEndpointBuilder().setClient(client).build();

endpoint.queryParamsForTest().setInt(QueryParams.LIST_TYPE, 2);
ListObjectResponse response = (ListObjectResponse) endpoint.get("b1").getEntity();

assertEquals(2, response.getContents().size());
assertNull(response.getContents().get(0).getOwner());
assertNull(response.getContents().get(1).getOwner());
}

@Test
public void listObjectOwnerOmittedForListV2WhenFetchOwnerFalse() throws OS3Exception, IOException {
OzoneClient client = createClientWithKeys("key1");
BucketEndpoint endpoint = newBucketEndpointBuilder().setClient(client).build();

endpoint.queryParamsForTest().setInt(QueryParams.LIST_TYPE, 2);
endpoint.queryParamsForTest().set(QueryParams.FETCH_OWNER, "false");
ListObjectResponse response = (ListObjectResponse) endpoint.get("b1").getEntity();

assertNull(response.getContents().get(0).getOwner());
}

@Test
public void listObjectOwnerIncludedForListV2WhenFetchOwnerTrue() throws OS3Exception, IOException {
OzoneClient client = createClientWithKeys("key1");
BucketEndpoint endpoint = newBucketEndpointBuilder().setClient(client).build();

endpoint.queryParamsForTest().setInt(QueryParams.LIST_TYPE, 2);
endpoint.queryParamsForTest().set(QueryParams.FETCH_OWNER, "true");
ListObjectResponse response = (ListObjectResponse) endpoint.get("b1").getEntity();

assertNotNull(response.getContents().get(0).getOwner());
}

private OzoneClient createClientWithKeys(String... keys) throws IOException {
OzoneClient client = new OzoneClientStub();

Expand Down