Skip to content

Commit 3fcf61f

Browse files
committed
Add getObject{Acl,Attributes} APIs
Signed-off-by: Bala.FA <[email protected]>
1 parent 0f533e8 commit 3fcf61f

17 files changed

+1022
-23
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2025 MinIO, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.minio;
18+
19+
/** Argument class of {@link MinioAsyncClient#getObjectAcl} and {@link MinioClient#getObjectAcl}. */
20+
public class GetObjectAclArgs extends ObjectVersionArgs {
21+
public static Builder builder() {
22+
return new Builder();
23+
}
24+
25+
/** Argument builder of {@link GetObjectAclArgs}. */
26+
public static final class Builder extends ObjectVersionArgs.Builder<Builder, GetObjectAclArgs> {}
27+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2025 MinIO, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.minio;
18+
19+
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.Objects;
22+
23+
/**
24+
* Argument class of {@link MinioAsyncClient#getObjectAttributes} and {@link
25+
* MinioClient#getObjectAttributes}.
26+
*/
27+
public class GetObjectAttributesArgs extends ObjectReadArgs {
28+
private List<String> objectAttributes;
29+
private Integer maxParts;
30+
private Integer partNumberMarker;
31+
32+
public List<String> objectAttributes() {
33+
return objectAttributes;
34+
}
35+
36+
public Integer maxParts() {
37+
return maxParts;
38+
}
39+
40+
public Integer partNumberMarker() {
41+
return partNumberMarker;
42+
}
43+
44+
public static Builder builder() {
45+
return new Builder();
46+
}
47+
48+
/** Argument builder of {@link GetObjectAttributesArgs}. */
49+
public static final class Builder
50+
extends ObjectReadArgs.Builder<Builder, GetObjectAttributesArgs> {
51+
@Override
52+
protected void validate(GetObjectAttributesArgs args) {
53+
super.validate(args);
54+
validateNotNull(args.objectAttributes, "object attributes");
55+
}
56+
57+
public Builder objectAttributes(String[] objectAttributes) {
58+
operations.add(
59+
args ->
60+
args.objectAttributes =
61+
objectAttributes == null ? null : Arrays.asList(objectAttributes));
62+
return this;
63+
}
64+
65+
public Builder objectAttributes(List<String> objectAttributes) {
66+
operations.add(args -> args.objectAttributes = objectAttributes);
67+
return this;
68+
}
69+
70+
public Builder maxParts(Integer maxParts) {
71+
operations.add(args -> args.maxParts = maxParts);
72+
return this;
73+
}
74+
75+
public Builder partNumberMarker(Integer partNumberMarker) {
76+
operations.add(args -> args.partNumberMarker = partNumberMarker);
77+
return this;
78+
}
79+
}
80+
81+
@Override
82+
public boolean equals(Object o) {
83+
if (this == o) return true;
84+
if (!(o instanceof GetObjectAttributesArgs)) return false;
85+
if (!super.equals(o)) return false;
86+
GetObjectAttributesArgs that = (GetObjectAttributesArgs) o;
87+
return Objects.equals(objectAttributes, that.objectAttributes)
88+
&& Objects.equals(maxParts, that.maxParts)
89+
&& Objects.equals(partNumberMarker, that.partNumberMarker);
90+
}
91+
92+
@Override
93+
public int hashCode() {
94+
return Objects.hash(super.hashCode(), objectAttributes, maxParts, partNumberMarker);
95+
}
96+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2025 MinIO, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.minio;
18+
19+
import io.minio.messages.GetObjectAttributesOutput;
20+
import okhttp3.Headers;
21+
22+
/**
23+
* Response class of {@link MinioAsyncClient#getObjectAttributes} and {@link
24+
* MinioClient#getObjectAttributes}.
25+
*/
26+
public class GetObjectAttributesResponse extends GenericResponse {
27+
private GetObjectAttributesOutput result;
28+
29+
public GetObjectAttributesResponse(
30+
Headers headers,
31+
String bucket,
32+
String region,
33+
String object,
34+
GetObjectAttributesOutput result) {
35+
super(headers, bucket, region, object);
36+
this.result = result;
37+
}
38+
39+
public GetObjectAttributesOutput result() {
40+
return result;
41+
}
42+
}

api/src/main/java/io/minio/MinioAsyncClient.java

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@
3232
import io.minio.errors.XmlParserException;
3333
import io.minio.http.HttpUtils;
3434
import io.minio.http.Method;
35+
import io.minio.messages.AccessControlPolicy;
3536
import io.minio.messages.Bucket;
3637
import io.minio.messages.CopyObjectResult;
3738
import io.minio.messages.CreateBucketConfiguration;
3839
import io.minio.messages.DeleteError;
3940
import io.minio.messages.DeleteObject;
41+
import io.minio.messages.GetObjectAttributesOutput;
4042
import io.minio.messages.Item;
4143
import io.minio.messages.LegalHold;
4244
import io.minio.messages.LifecycleConfiguration;
@@ -66,6 +68,7 @@
6668
import java.nio.file.StandardOpenOption;
6769
import java.security.InvalidKeyException;
6870
import java.security.NoSuchAlgorithmException;
71+
import java.time.ZonedDateTime;
6972
import java.util.Arrays;
7073
import java.util.Date;
7174
import java.util.Iterator;
@@ -3151,6 +3154,111 @@ public CompletableFuture<Void> deleteObjectTags(DeleteObjectTagsArgs args)
31513154
return executeDeleteAsync(args, null, queryParams).thenAccept(response -> response.close());
31523155
}
31533156

3157+
/**
3158+
* Gets access control policy of an object.
3159+
*
3160+
* <pre>Example:{@code
3161+
* CompletableFuture<AccessControlPolicy> future =
3162+
* minioAsyncClient.getObjectAcl(
3163+
* GetObjectAclArgs.builder().bucket("my-bucketname").object("my-objectname").build());
3164+
* }</pre>
3165+
*
3166+
* @param args {@link GetObjectAclArgs} object.
3167+
* @return {@link CompletableFuture}&lt;{@link AccessControlPolicy}&gt; object.
3168+
* @throws InsufficientDataException thrown to indicate not enough data available in InputStream.
3169+
* @throws InternalException thrown to indicate internal library error.
3170+
* @throws InvalidKeyException thrown to indicate missing of HMAC SHA-256 library.
3171+
* @throws IOException thrown to indicate I/O error on S3 operation.
3172+
* @throws NoSuchAlgorithmException thrown to indicate missing of MD5 or SHA-256 digest library.
3173+
* @throws XmlParserException thrown to indicate XML parsing error.
3174+
*/
3175+
public CompletableFuture<AccessControlPolicy> getObjectAcl(GetObjectAclArgs args)
3176+
throws InsufficientDataException, InternalException, InvalidKeyException, IOException,
3177+
NoSuchAlgorithmException, XmlParserException {
3178+
checkArgs(args);
3179+
Multimap<String, String> queryParams = newMultimap("acl", "");
3180+
if (args.versionId() != null) queryParams.put("versionId", args.versionId());
3181+
return executeGetAsync(args, null, queryParams)
3182+
.thenApply(
3183+
response -> {
3184+
try {
3185+
return Xml.unmarshal(AccessControlPolicy.class, response.body().charStream());
3186+
} catch (XmlParserException e) {
3187+
throw new CompletionException(e);
3188+
} finally {
3189+
response.close();
3190+
}
3191+
});
3192+
}
3193+
3194+
/**
3195+
* Gets attributes of an object.
3196+
*
3197+
* <pre>Example:{@code
3198+
* CompletableFuture<GetObjectAttributesResponse> future =
3199+
* minioAsyncClient.getObjectAttributes(
3200+
* GetObjectAttributesArgs.builder()
3201+
* .bucket("my-bucketname")
3202+
* .object("my-objectname")
3203+
* .objectAttributes(
3204+
* new String[] {
3205+
* "ETag", "Checksum", "ObjectParts", "StorageClass", "ObjectSize"
3206+
* })
3207+
* .build());
3208+
* }</pre>
3209+
*
3210+
* @param args {@link GetObjectAttributesArgs} object.
3211+
* @return {@link CompletableFuture}&lt;{@link GetObjectAttributesResponse}&gt; object.
3212+
* @throws InsufficientDataException thrown to indicate not enough data available in InputStream.
3213+
* @throws InternalException thrown to indicate internal library error.
3214+
* @throws InvalidKeyException thrown to indicate missing of HMAC SHA-256 library.
3215+
* @throws IOException thrown to indicate I/O error on S3 operation.
3216+
* @throws NoSuchAlgorithmException thrown to indicate missing of MD5 or SHA-256 digest library.
3217+
* @throws XmlParserException thrown to indicate XML parsing error.
3218+
*/
3219+
public CompletableFuture<GetObjectAttributesResponse> getObjectAttributes(
3220+
GetObjectAttributesArgs args)
3221+
throws InsufficientDataException, InternalException, InvalidKeyException, IOException,
3222+
NoSuchAlgorithmException, XmlParserException {
3223+
checkArgs(args);
3224+
3225+
Multimap<String, String> queryParams = newMultimap("attributes", "");
3226+
if (args.versionId() != null) queryParams.put("versionId", args.versionId());
3227+
3228+
Multimap<String, String> headers = HashMultimap.create();
3229+
if (args.maxParts() != null) headers.put("x-amz-max-parts", args.maxParts().toString());
3230+
if (args.partNumberMarker() != null) {
3231+
headers.put("x-amz-part-number-marker", args.partNumberMarker().toString());
3232+
}
3233+
for (String attribute : args.objectAttributes()) {
3234+
if (attribute != null) headers.put("x-amz-object-attributes", attribute);
3235+
}
3236+
3237+
return executeGetAsync(args, headers, queryParams)
3238+
.thenApply(
3239+
response -> {
3240+
try {
3241+
GetObjectAttributesOutput result =
3242+
Xml.unmarshal(GetObjectAttributesOutput.class, response.body().charStream());
3243+
3244+
String value = response.headers().get("x-amz-delete-marker");
3245+
if (value != null) result.setDeleteMarker(Boolean.valueOf(value));
3246+
value = response.headers().get("Last-Modified");
3247+
if (value != null) {
3248+
result.setLastModified(ZonedDateTime.parse(value, Time.HTTP_HEADER_DATE_FORMAT));
3249+
}
3250+
result.setVersionId(response.headers().get("x-amz-version-id"));
3251+
3252+
return new GetObjectAttributesResponse(
3253+
response.headers(), args.bucket(), args.region(), args.object(), result);
3254+
} catch (XmlParserException e) {
3255+
throw new CompletionException(e);
3256+
} finally {
3257+
response.close();
3258+
}
3259+
});
3260+
}
3261+
31543262
/**
31553263
* Uploads multiple objects in a single put call. It is done by creating intermediate TAR file
31563264
* optionally compressed which is uploaded to S3 service.

api/src/main/java/io/minio/MinioClient.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.minio.errors.InvalidResponseException;
2727
import io.minio.errors.ServerException;
2828
import io.minio.errors.XmlParserException;
29+
import io.minio.messages.AccessControlPolicy;
2930
import io.minio.messages.Bucket;
3031
import io.minio.messages.DeleteError;
3132
import io.minio.messages.Item;
@@ -2275,6 +2276,83 @@ public void deleteObjectTags(DeleteObjectTagsArgs args)
22752276
}
22762277
}
22772278

2279+
/**
2280+
* Gets access control policy of an object.
2281+
*
2282+
* <pre>Example:{@code
2283+
* AccessControlPolicy policy =
2284+
* minioClient.getObjectAcl(
2285+
* GetObjectAclArgs.builder().bucket("my-bucketname").object("my-objectname").build());
2286+
* }</pre>
2287+
*
2288+
* @param args {@link GetObjectAclArgs} object.
2289+
* @return {@link AccessControlPolicy} - Access control policy object.
2290+
* @throws ErrorResponseException thrown to indicate S3 service returned an error response.
2291+
* @throws InsufficientDataException thrown to indicate not enough data available in InputStream.
2292+
* @throws InternalException thrown to indicate internal library error.
2293+
* @throws InvalidKeyException thrown to indicate missing of HMAC SHA-256 library.
2294+
* @throws InvalidResponseException thrown to indicate S3 service returned invalid or no error
2295+
* response.
2296+
* @throws IOException thrown to indicate I/O error on S3 operation.
2297+
* @throws NoSuchAlgorithmException thrown to indicate missing of MD5 or SHA-256 digest library.
2298+
* @throws XmlParserException thrown to indicate XML parsing error.
2299+
*/
2300+
public AccessControlPolicy getObjectAcl(GetObjectAclArgs args)
2301+
throws ErrorResponseException, InsufficientDataException, InternalException,
2302+
InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException,
2303+
ServerException, XmlParserException {
2304+
try {
2305+
return asyncClient.getObjectAcl(args).get();
2306+
} catch (InterruptedException e) {
2307+
throw new RuntimeException(e);
2308+
} catch (ExecutionException e) {
2309+
asyncClient.throwEncapsulatedException(e);
2310+
return null;
2311+
}
2312+
}
2313+
2314+
/**
2315+
* Gets attributes of an object.
2316+
*
2317+
* <pre>Example:{@code
2318+
* GetObjectAttributesResponse response =
2319+
* minioClient.getObjectAttributes(
2320+
* GetObjectAttributesArgs.builder()
2321+
* .bucket("my-bucketname")
2322+
* .object("my-objectname")
2323+
* .objectAttributes(
2324+
* new String[] {
2325+
* "ETag", "Checksum", "ObjectParts", "StorageClass", "ObjectSize"
2326+
* })
2327+
* .build());
2328+
* }</pre>
2329+
*
2330+
* @param args {@link GetObjectAttributesArgs} object.
2331+
* @return {@link GetObjectAttributesResponse} - Response object.
2332+
* @throws ErrorResponseException thrown to indicate S3 service returned an error response.
2333+
* @throws InsufficientDataException thrown to indicate not enough data available in InputStream.
2334+
* @throws InternalException thrown to indicate internal library error.
2335+
* @throws InvalidKeyException thrown to indicate missing of HMAC SHA-256 library.
2336+
* @throws InvalidResponseException thrown to indicate S3 service returned invalid or no error
2337+
* response.
2338+
* @throws IOException thrown to indicate I/O error on S3 operation.
2339+
* @throws NoSuchAlgorithmException thrown to indicate missing of MD5 or SHA-256 digest library.
2340+
* @throws XmlParserException thrown to indicate XML parsing error.
2341+
*/
2342+
public GetObjectAttributesResponse getObjectAttributes(GetObjectAttributesArgs args)
2343+
throws ErrorResponseException, InsufficientDataException, InternalException,
2344+
InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException,
2345+
ServerException, XmlParserException {
2346+
try {
2347+
return asyncClient.getObjectAttributes(args).get();
2348+
} catch (InterruptedException e) {
2349+
throw new RuntimeException(e);
2350+
} catch (ExecutionException e) {
2351+
asyncClient.throwEncapsulatedException(e);
2352+
return null;
2353+
}
2354+
}
2355+
22782356
/**
22792357
* Uploads multiple objects in a single put call. It is done by creating intermediate TAR file
22802358
* optionally compressed which is uploaded to S3 service.

0 commit comments

Comments
 (0)