From 4a530332c6324191d0c84cf75cd274e143723a38 Mon Sep 17 00:00:00 2001 From: "Bala.FA" Date: Mon, 1 Jun 2020 09:57:05 +0530 Subject: [PATCH] Handle extra headers/query params for all requests. --- api/src/main/java/io/minio/MinioClient.java | 793 ++++++++---------- .../test/java/io/minio/MinioClientTest.java | 3 +- 2 files changed, 368 insertions(+), 428 deletions(-) diff --git a/api/src/main/java/io/minio/MinioClient.java b/api/src/main/java/io/minio/MinioClient.java index bcb3dd086..76cfbd56e 100755 --- a/api/src/main/java/io/minio/MinioClient.java +++ b/api/src/main/java/io/minio/MinioClient.java @@ -105,7 +105,6 @@ import java.time.ZonedDateTime; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -168,19 +167,14 @@ *

Examples on using this library are available here. * - *

Use {@code MinioClient.builder()} to create S3 client. - * {@code - * // Create client with anonymous access. - * MinioClient minioClient = MinioClient.builder() - * .endpoint("https://play.min.io") - * .build(); + *

Use {@code MinioClient.builder()} to create S3 client. * - * // Create client with credentials. - * MinioClient minioClient = MinioClient.builder() - * .endpoint("https://play.min.io") - * .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG") - * .build(); - * } + * {@code // Create client with anonymous access. MinioClient minioClient = MinioClient.builder() + * .endpoint("https://play.min.io") .build(); + * + *

// Create client with credentials. MinioClient minioClient = MinioClient.builder() + * .endpoint("https://play.min.io") .credentials("Q3AM3UQ867SPQQA43P2F", + * "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG") .build(); } */ @SuppressWarnings({"SameParameterValue", "WeakerAccess"}) public class MinioClient { @@ -709,20 +703,15 @@ private void checkReadRequestSse(ServerSideEncryption sse) throws IllegalArgumen } } - private Map normalizeHeaders(Map headerMap) { - Map normHeaderMap = new HashMap(); - for (Map.Entry entry : headerMap.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - String keyLowerCased = key.toLowerCase(Locale.US); - if (amzHeaders.contains(keyLowerCased)) { - key = "x-amz-" + key; - } else if (!standardHeaders.contains(keyLowerCased) && !keyLowerCased.startsWith("x-amz-")) { - key = "x-amz-meta-" + key; - } - normHeaderMap.put(key, value); + private Multimap merge(Multimap m1, Multimap m2) { + Multimap map = HashMultimap.create(); + if (m1 != null) { + map.putAll(m1); + } + if (m2 != null) { + map.putAll(m2); } - return normHeaderMap; + return map; } private HttpUrl buildUrl( @@ -915,6 +904,41 @@ private Request createRequest( return requestBuilder.build(); } + private Response execute( + Method method, + BaseArgs args, + Multimap headers, + Multimap queryParams, + Object body, + int length) + throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, + InternalException, InvalidBucketNameException, InvalidKeyException, + InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, + XmlParserException { + String bucketName = null; + String region = null; + String objectName = null; + + if (args instanceof BucketArgs) { + bucketName = ((BucketArgs) args).bucket(); + region = ((BucketArgs) args).region(); + } + + if (args instanceof ObjectArgs) { + objectName = ((ObjectArgs) args).object(); + } + + return execute( + method, + bucketName, + objectName, + getRegion(bucketName, region), + merge(args.extraHeaders(), headers), + merge(args.extraQueryParams(), queryParams), + body, + length); + } + private Response execute( Method method, String bucketName, @@ -994,7 +1018,6 @@ private Response execute( if (this.traceStream != null) { this.traceStream.println(END_HTTP); } - // response.headers().toMultimap(); return response; } @@ -1108,39 +1131,21 @@ private Response execute( throw new ErrorResponseException(errorResponse, response); } - private Response execute( - Method method, - String bucketName, - String objectName, - String region, - Map headerMap, - Map queryParamMap, - Object body, - int length) + /** Returns region of given bucket either from region cache or set in constructor. */ + private String getRegion(String bucketName, String region) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - Multimap headerMultiMap = null; - if (headerMap != null) { - headerMultiMap = Multimaps.forMap(normalizeHeaders(headerMap)); - } - - Multimap queryParamMultiMap = null; - if (queryParamMap != null) { - queryParamMultiMap = Multimaps.forMap(queryParamMap); + if (region != null) { + // Error out if region does not match with region passed via constructor. + if (this.region != null && !this.region.equals(region)) { + throw new IllegalArgumentException( + "region must be " + this.region + ", but passed " + region); + } + return region; } - return execute( - method, bucketName, objectName, region, headerMultiMap, queryParamMultiMap, body, length); - } - - /** Returns region of given bucket either from region cache or set in constructor. */ - private String getRegion(String bucketName) - throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, - InternalException, InvalidBucketNameException, InvalidKeyException, - InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, - XmlParserException { if (this.region != null && !this.region.equals("")) { return this.region; } @@ -1149,17 +1154,17 @@ private String getRegion(String bucketName) return US_EAST_1; } - String region = AwsRegionCache.INSTANCE.get(bucketName); + region = AwsRegionCache.INSTANCE.get(bucketName); if (region != null) { return region; } // Execute GetBucketLocation REST API to get region of the bucket. - Map queryParamMap = new HashMap<>(); - queryParamMap.put("location", null); + Multimap queryParams = HashMultimap.create(); + queryParams.put("location", null); Response response = - execute(Method.GET, bucketName, null, US_EAST_1, null, queryParamMap, null, 0); + execute(Method.GET, bucketName, null, US_EAST_1, null, queryParams, null, 0); try (ResponseBody body = response.body()) { LocationConstraint lc = Xml.unmarshal(LocationConstraint.class, body.charStream()); @@ -1177,65 +1182,24 @@ private String getRegion(String bucketName) } private Response executeGet( - String bucketName, - String objectName, - Map headerMap, - Map queryParamMap) + BaseArgs args, Multimap headers, Multimap queryParams) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - return execute( - Method.GET, - bucketName, - objectName, - getRegion(bucketName), - headerMap, - queryParamMap, - null, - 0); - } - - private Response executeGet( - String bucketName, String objectName, Multimap queryParamMap) - throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, - InternalException, InvalidBucketNameException, InvalidKeyException, - InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, - XmlParserException { - return execute( - Method.GET, bucketName, objectName, getRegion(bucketName), null, queryParamMap, null, 0); + return execute(Method.GET, args, headers, queryParams, null, 0); } private Response executeHead( - String bucketName, - String objectName, - Multimap headers, - Multimap queryParams) - throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, - InternalException, InvalidBucketNameException, InvalidKeyException, - InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, - XmlParserException { - Response response = - execute( - Method.HEAD, - bucketName, - objectName, - getRegion(bucketName), - headers, - queryParams, - null, - 0); - response.body().close(); - return response; - } - - private Response executeHead(String bucketName, String objectName) + BaseArgs args, Multimap headers, Multimap queryParams) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { try { - return executeHead(bucketName, objectName, null, null); + Response response = execute(Method.HEAD, args, headers, queryParams, null, 0); + response.body().close(); + return response; } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.RETRY_HEAD_BUCKET) { throw e; @@ -1243,102 +1207,45 @@ private Response executeHead(String bucketName, String objectName) } // Retry once for RETRY_HEAD_BUCKET error. - return executeHead(bucketName, objectName, null, null); - } - - private Response executeDelete( - String bucketName, - String objectName, - Multimap headers, - Multimap queryParams) - throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, - InternalException, InvalidBucketNameException, InvalidKeyException, - InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, - XmlParserException { - Response response = - execute( - Method.DELETE, - bucketName, - objectName, - getRegion(bucketName), - headers, - queryParams, - null, - 0); + Response response = execute(Method.HEAD, args, headers, queryParams, null, 0); response.body().close(); return response; } private Response executeDelete( - String bucketName, String objectName, Map queryParamMap) + BaseArgs args, Multimap headers, Multimap queryParams) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - Response response = - execute( - Method.DELETE, - bucketName, - objectName, - getRegion(bucketName), - null, - queryParamMap, - null, - 0); + Response response = execute(Method.DELETE, args, headers, queryParams, null, 0); response.body().close(); return response; } private Response executePost( - String bucketName, - String objectName, - Map headerMap, - Map queryParamMap, + BaseArgs args, + Multimap headers, + Multimap queryParams, Object data) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - return execute( - Method.POST, - bucketName, - objectName, - getRegion(bucketName), - headerMap, - queryParamMap, - data, - 0); + return execute(Method.POST, args, headers, queryParams, data, 0); } private Response executePut( - String bucketName, - String objectName, - String region, - Map headerMap, - Map queryParamMap, - Object data, - int length) - throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, - InternalException, InvalidBucketNameException, InvalidKeyException, - InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, - XmlParserException { - return execute( - Method.PUT, bucketName, objectName, region, headerMap, queryParamMap, data, length); - } - - private Response executePut( - String bucketName, - String objectName, - Map headerMap, - Map queryParamMap, + BaseArgs args, + Multimap headers, + Multimap queryParams, Object data, int length) throws ErrorResponseException, IllegalArgumentException, InsufficientDataException, InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - return executePut( - bucketName, objectName, getRegion(bucketName), headerMap, queryParamMap, data, length); + return execute(Method.PUT, args, headers, queryParams, data, length); } /** @@ -1470,21 +1377,19 @@ public ObjectStat statObject(StatObjectArgs args) checkArgs(args); args.validateSsec(baseUrl); - Multimap headers = HashMultimap.create(); - headers.putAll(args.extraHeaders()); + Multimap ssecHeaders = null; if (args.ssec() != null) { - headers.putAll(Multimaps.forMap(args.ssec().headers())); + ssecHeaders = Multimaps.forMap(args.ssec().headers()); } - Multimap queryParams = HashMultimap.create(); - queryParams.putAll(args.extraQueryParams()); + Multimap queryParams = null; if (args.versionId() != null) { + queryParams = HashMultimap.create(); queryParams.put("versionId", args.versionId()); } - try (Response response = executeHead(args.bucket(), args.object(), headers, queryParams)) { - return new ObjectStat(args.bucket(), args.object(), response.headers()); - } + Response response = executeHead(args, ssecHeaders, queryParams); + return new ObjectStat(args.bucket(), args.object(), response.headers()); } /** @@ -1515,7 +1420,8 @@ public String getObjectUrl(String bucketName, String objectName) InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { checkObjectName(objectName); - HttpUrl url = buildUrl(Method.GET, bucketName, objectName, getRegion(bucketName), null); + HttpUrl url = + buildUrl(Method.GET, bucketName, objectName, getRegion(bucketName, this.region), null); return url.toString(); } @@ -1764,31 +1670,27 @@ public InputStream getObject(GetObjectArgs args) InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - Long offset = args.offset(); - Long length = args.length(); - ServerSideEncryptionCustomerKey ssec = args.ssec(); + checkArgs(args); args.validateSsec(this.baseUrl); + Long offset = args.offset(); + Long length = args.length(); if (length != null && offset == null) { offset = 0L; } - Map headerMap = null; - if (offset != null || length != null || ssec != null) { - headerMap = new HashMap<>(); - } - + Multimap headers = HashMultimap.create(); if (length != null) { - headerMap.put("Range", "bytes=" + offset + "-" + (offset + length - 1)); + headers.put("Range", "bytes=" + offset + "-" + (offset + length - 1)); } else if (offset != null) { - headerMap.put("Range", "bytes=" + offset + "-"); + headers.put("Range", "bytes=" + offset + "-"); } - if (ssec != null) { - headerMap.putAll(ssec.headers()); + if (args.ssec() != null) { + headers.putAll(Multimaps.forMap(args.ssec().headers())); } - Response response = executeGet(args.bucket(), args.object(), headerMap, null); + Response response = executeGet(args, headers, null); return response.body().byteStream(); } @@ -2217,17 +2119,7 @@ public ObjectWriteResponse copyObject(CopyObjectArgs args) headers.put("x-amz-tagging-directive", args.taggingDirective().name()); } - try (Response response = - execute( - Method.PUT, - args.bucket(), - args.object(), - getRegion(args.bucket()), - headers, - null, - null, - 0)) { - + try (Response response = executePut(args, headers, null, null, 0)) { CopyObjectResult result = Xml.unmarshal(CopyObjectResult.class, response.body().charStream()); return new ObjectWriteResponse( response.headers(), @@ -2545,7 +2437,13 @@ public ObjectWriteResponse composeObject(ComposeObjectArgs args) } return completeMultipartUpload( - args.bucket(), getRegion(args.bucket()), args.object(), uploadId, totalParts, null, null); + args.bucket(), + getRegion(args.bucket(), args.region()), + args.object(), + uploadId, + totalParts, + null, + null); } catch (RuntimeException e) { if (!(args.sources().size() == 1 && args.sources().get(0).offset() == null @@ -2687,7 +2585,7 @@ public String getPresignedObjectUrl(GetPresignedObjectUrlArgs args) body = EMPTY_BODY; } - String region = getRegion(args.bucket()); + String region = getRegion(args.bucket(), args.region()); HttpUrl url = buildUrl(args.method(), args.bucket(), args.object(), region, args.extraQueryParams()); Request request = createRequest(url, args.method(), null, body, 0); @@ -2950,7 +2848,7 @@ public Map presignedPostPolicy(PostPolicy policy) InternalException, InvalidBucketNameException, InvalidExpiresRangeException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - return policy.formData(this.accessKey, this.secretKey, getRegion(policy.bucketName())); + return policy.formData(this.accessKey, this.secretKey, getRegion(policy.bucketName(), null)); } /** @@ -3030,19 +2928,19 @@ public void removeObject(RemoveObjectArgs args) XmlParserException { checkArgs(args); - Multimap headers = HashMultimap.create(); - headers.putAll(args.extraHeaders()); + Multimap headers = null; if (args.bypassGovernanceMode()) { + headers = HashMultimap.create(); headers.put("x-amz-bypass-governance-retention", "true"); } - Multimap queryParams = HashMultimap.create(); - queryParams.putAll(args.extraQueryParams()); + Multimap queryParams = null; if (args.versionId() != null) { + queryParams = HashMultimap.create(); queryParams.put("versionId", args.versionId()); } - executeDelete(args.bucket(), args.object(), headers, queryParams); + executeDelete(args, headers, queryParams); } /** @@ -3695,10 +3593,11 @@ public List listBuckets() InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { - Response response = executeGet(null, null, (Multimap) null); - try (ResponseBody body = response.body()) { + try (Response response = + execute( + Method.GET, null, null, (region != null) ? region : US_EAST_1, null, null, null, 0)) { ListAllMyBucketsResult result = - Xml.unmarshal(ListAllMyBucketsResult.class, body.charStream()); + Xml.unmarshal(ListAllMyBucketsResult.class, response.body().charStream()); return result.buckets(); } } @@ -3773,7 +3672,7 @@ public boolean bucketExists(BucketExistsArgs args) InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { try { - executeHead(args.bucket(), null); + executeHead(args, null, null); return true; } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.NO_SUCH_BUCKET) { @@ -3927,17 +3826,19 @@ public void makeBucket(MakeBucketArgs args) ServerException, XmlParserException { checkArgs(args); - String region = US_EAST_1; - if (args.region() != null && !args.region().isEmpty()) { - region = args.region(); - } else if (this.region != null && !this.region.isEmpty()) { + String region = args.region(); + if (this.region != null && !this.region.isEmpty()) { + // Error out if region does not match with region passed via constructor. + if (region != null && !region.equals(this.region)) { + throw new IllegalArgumentException( + "region must be " + this.region + ", but passed " + region); + } + region = this.region; } - // If constructor already sets a region, check if it is equal to region param if provided - if (this.region != null && !this.region.equals(region)) { - throw new RegionConflictException( - "passed region conflicts with the one previously specified"); + if (region == null) { + region = US_EAST_1; } CreateBucketConfiguration config = null; @@ -3945,17 +3846,26 @@ public void makeBucket(MakeBucketArgs args) config = new CreateBucketConfiguration(region); } - Map headerMap = null; + Multimap headers = null; if (args.objectLock()) { - headerMap = new HashMap<>(); - headerMap.put("x-amz-bucket-object-lock-enabled", "true"); + headers = HashMultimap.create(); + headers.put("x-amz-bucket-object-lock-enabled", "true"); } - Response response = executePut(args.bucket(), null, region, headerMap, null, config, 0); - if (isAwsHost) { - AwsRegionCache.INSTANCE.set(args.bucket(), region); + try (Response response = + execute( + Method.PUT, + args.bucket(), + null, + region, + merge(args.extraHeaders(), headers), + args.extraQueryParams(), + config, + 0)) { + if (isAwsHost) { + AwsRegionCache.INSTANCE.set(args.bucket(), region); + } } - response.close(); } /** @@ -4015,12 +3925,11 @@ public void enableVersioning(EnableVersioningArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("versioning", ""); - VersioningConfiguration config = new VersioningConfiguration(true); + Multimap queryParams = HashMultimap.create(); + queryParams.put("versioning", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, config, 0); - response.body().close(); + Response response = executePut(args, null, queryParams, new VersioningConfiguration(true), 0); + response.close(); } /** @@ -4081,11 +3990,11 @@ public void disableVersioning(DisableVersioningArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("versioning", ""); - VersioningConfiguration config = new VersioningConfiguration(false); - Response response = executePut(args.bucket(), null, null, queryParamMap, config, 0); - response.body().close(); + Multimap queryParams = HashMultimap.create(); + queryParams.put("versioning", ""); + + Response response = executePut(args, null, queryParams, new VersioningConfiguration(false), 0); + response.close(); } /** @@ -4122,9 +4031,10 @@ public boolean isVersioningEnabled(IsVersioningEnabledArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("versioning", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + Multimap queryParams = HashMultimap.create(); + queryParams.put("versioning", ""); + + try (Response response = executeGet(args, null, queryParams)) { VersioningConfiguration result = Xml.unmarshal(VersioningConfiguration.class, response.body().charStream()); return result.status(); @@ -4195,10 +4105,10 @@ public void setDefaultRetention(SetDefaultRetentionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("object-lock", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("object-lock", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, args.config(), 0); + Response response = executePut(args, null, queryParams, args.config(), 0); response.close(); } @@ -4230,11 +4140,10 @@ public void deleteDefaultRetention(DeleteDefaultRetentionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("object-lock", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("object-lock", ""); - Response response = - executePut(args.bucket(), null, null, queryParamMap, new ObjectLockConfiguration(), 0); + Response response = executePut(args, null, queryParams, new ObjectLockConfiguration(), 0); response.close(); } @@ -4305,10 +4214,10 @@ public ObjectLockConfiguration getDefaultRetention(GetDefaultRetentionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("object-lock", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("object-lock", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { return Xml.unmarshal(ObjectLockConfiguration.class, response.body().charStream()); } } @@ -4398,21 +4307,20 @@ public void setObjectRetention(SetObjectRetentionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("retention", ""); - + Multimap queryParams = HashMultimap.create(); + queryParams.put("retention", ""); if (args.versionId() != null) { - queryParamMap.put("versionId", args.versionId()); + queryParams.put("versionId", args.versionId()); } - Map headerMap = new HashMap<>(); + Multimap headers = null; if (args.bypassGovernanceMode()) { - headerMap.put("x-amz-bypass-governance-retention", "True"); + headers = HashMultimap.create(); + headers.put("x-amz-bypass-governance-retention", "True"); } - Response response = - executePut(args.bucket(), args.object(), headerMap, queryParamMap, args.config(), 0); - response.body().close(); + Response response = executePut(args, headers, queryParams, args.config(), 0); + response.close(); } /** @@ -4491,16 +4399,14 @@ public Retention getObjectRetention(GetObjectRetentionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("retention", ""); - + Multimap queryParams = HashMultimap.create(); + queryParams.put("retention", ""); if (args.versionId() != null) { - queryParamMap.put("versionId", args.versionId()); + queryParams.put("versionId", args.versionId()); } - try (Response response = executeGet(args.bucket(), args.object(), null, queryParamMap)) { - Retention retention = Xml.unmarshal(Retention.class, response.body().charStream()); - return retention; + try (Response response = executeGet(args, null, queryParams)) { + return Xml.unmarshal(Retention.class, response.body().charStream()); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.NO_SUCH_OBJECT_LOCK_CONFIGURATION) { throw e; @@ -4577,16 +4483,15 @@ public void enableObjectLegalHold(EnableObjectLegalHoldArgs args) InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("legal-hold", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("legal-hold", ""); if (args.versionId() != null) { - queryParamMap.put("versionId", args.versionId()); + queryParams.put("versionId", args.versionId()); } - LegalHold legalHold = new LegalHold(true); - Response response = executePut(args.bucket(), args.object(), null, queryParamMap, legalHold, 0); - response.body().close(); + Response response = executePut(args, null, queryParams, new LegalHold(true), 0); + response.close(); } /** @@ -4658,16 +4563,14 @@ public void disableObjectLegalHold(DisableObjectLegalHoldArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("legal-hold", ""); - + Multimap queryParams = HashMultimap.create(); + queryParams.put("legal-hold", ""); if (args.versionId() != null) { - queryParamMap.put("versionId", args.versionId()); + queryParams.put("versionId", args.versionId()); } - LegalHold legalHold = new LegalHold(false); - Response response = executePut(args.bucket(), args.object(), null, queryParamMap, legalHold, 0); - response.body().close(); + Response response = executePut(args, null, queryParams, new LegalHold(false), 0); + response.close(); } /** @@ -4754,14 +4657,13 @@ public boolean isObjectLegalHoldEnabled(IsObjectLegalHoldEnabledArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("legal-hold", ""); - + Multimap queryParams = HashMultimap.create(); + queryParams.put("legal-hold", ""); if (args.versionId() != null) { - queryParamMap.put("versionId", args.versionId()); + queryParams.put("versionId", args.versionId()); } - try (Response response = executeGet(args.bucket(), args.object(), null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { LegalHold result = Xml.unmarshal(LegalHold.class, response.body().charStream()); return result.status(); } catch (ErrorResponseException e) { @@ -4828,8 +4730,7 @@ public void removeBucket(RemoveBucketArgs args) InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { checkArgs(args); - - executeDelete(args.bucket(), null, null); + executeDelete(args, null, null); } private ObjectWriteResponse putObject( @@ -5190,10 +5091,10 @@ public String getBucketPolicy(GetBucketPolicyArgs args) ServerException, XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("policy", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("policy", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { byte[] buf = new byte[MAX_BUCKET_POLICY_SIZE]; int bytesRead = 0; bytesRead = response.body().byteStream().read(buf, 0, MAX_BUCKET_POLICY_SIZE); @@ -5329,13 +5230,13 @@ public void setBucketPolicy(SetBucketPolicyArgs args) XmlParserException { checkArgs(args); - Map headerMap = new HashMap<>(); - headerMap.put("Content-Type", "application/json"); + Multimap queryParams = HashMultimap.create(); + queryParams.put("policy", ""); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("policy", ""); + Multimap headers = HashMultimap.create(); + headers.put("Content-Type", "application/json"); - Response response = executePut(args.bucket(), null, headerMap, queryParamMap, args.config(), 0); + Response response = executePut(args, headers, queryParams, args.config(), 0); response.close(); } @@ -5366,12 +5267,11 @@ public void deleteBucketPolicy(DeleteBucketPolicyArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("policy", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("policy", ""); try { - Response response = executeDelete(args.bucket(), "", queryParamMap); - response.close(); + executeDelete(args, null, queryParams); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.NO_SUCH_BUCKET_POLICY) { throw e; @@ -5463,9 +5363,10 @@ public void setBucketLifeCycle(SetBucketLifeCycleArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("lifecycle", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, args.config(), 0); + Multimap queryParams = HashMultimap.create(); + queryParams.put("lifecycle", ""); + + Response response = executePut(args, null, queryParams, args.config(), 0); response.close(); } @@ -5526,10 +5427,10 @@ public void deleteBucketLifeCycle(DeleteBucketLifeCycleArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("lifecycle", ""); - Response response = executeDelete(args.bucket(), "", queryParamMap); - response.close(); + Multimap queryParams = HashMultimap.create(); + queryParams.put("lifecycle", ""); + + executeDelete(args, null, queryParams); } /** @@ -5593,9 +5494,10 @@ public String getBucketLifeCycle(GetBucketLifeCycleArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("lifecycle", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + Multimap queryParams = HashMultimap.create(); + queryParams.put("lifecycle", ""); + + try (Response response = executeGet(args, null, queryParams)) { return new String(response.body().bytes(), StandardCharsets.UTF_8); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.NO_SUCH_LIFECYCLE_CONFIGURATION) { @@ -5668,10 +5570,10 @@ public NotificationConfiguration getBucketNotification(GetBucketNotificationArgs XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("notification", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("notification", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { return Xml.unmarshal(NotificationConfiguration.class, response.body().charStream()); } } @@ -5772,9 +5674,9 @@ public void setBucketNotification(SetBucketNotificationArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("notification", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, args.config(), 0); + Multimap queryParams = HashMultimap.create(); + queryParams.put("notification", ""); + Response response = executePut(args, null, queryParams, args.config(), 0); response.close(); } @@ -5836,11 +5738,10 @@ public void deleteBucketNotification(DeleteBucketNotificationArgs args) XmlParserException { checkArgs(args); - setBucketNotification( - SetBucketNotificationArgs.builder() - .bucket(args.bucket()) - .config(new NotificationConfiguration()) - .build()); + Multimap queryParams = HashMultimap.create(); + queryParams.put("notification", ""); + Response response = executePut(args, null, queryParams, new NotificationConfiguration(), 0); + response.close(); } /** @@ -6450,14 +6351,14 @@ public CloseableIterator> listenBucketNotification( XmlParserException { checkArgs(args); - Multimap queryParamMap = HashMultimap.create(); - queryParamMap.put("prefix", args.prefix()); - queryParamMap.put("suffix", args.suffix()); + Multimap queryParams = HashMultimap.create(); + queryParams.put("prefix", args.prefix()); + queryParams.put("suffix", args.suffix()); for (String event : args.events()) { - queryParamMap.put("events", event); + queryParams.put("events", event); } - Response response = executeGet(args.bucket(), "", queryParamMap); + Response response = executeGet(args, null, queryParams); NotificationResultRecords result = new NotificationResultRecords(response); return result.closeableIterator(); } @@ -6591,27 +6492,30 @@ public SelectResponseStream selectObjectContent(SelectObjectContentArgs args) InternalException, InvalidBucketNameException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException { + checkArgs(args); args.validateSsec(this.baseUrl); - Map headerMap = null; + Multimap headers = null; if (args.ssec() != null) { - headerMap = args.ssec().headers(); + headers = Multimaps.forMap(args.ssec().headers()); } - Map queryParamMap = new HashMap<>(); - queryParamMap.put("select", ""); - queryParamMap.put("select-type", "2"); + Multimap queryParams = HashMultimap.create(); + queryParams.put("select", ""); + queryParams.put("select-type", "2"); - SelectObjectContentRequest request = - new SelectObjectContentRequest( - args.sqlExpression(), - args.requestProgress(), - args.inputSerialization(), - args.outputSerialization(), - args.scanStartRange(), - args.scanEndRange()); Response response = - executePost(args.bucket(), args.object(), headerMap, queryParamMap, request); + executePost( + args, + headers, + queryParams, + new SelectObjectContentRequest( + args.sqlExpression(), + args.requestProgress(), + args.inputSerialization(), + args.outputSerialization(), + args.scanStartRange(), + args.scanEndRange())); return new SelectResponseStream(response.body().byteStream()); } @@ -6643,9 +6547,10 @@ public void setBucketEncryption(SetBucketEncryptionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("encryption", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, args.config(), 0); + Multimap queryParams = HashMultimap.create(); + queryParams.put("encryption", ""); + + Response response = executePut(args, null, queryParams, args.config(), 0); response.close(); } @@ -6679,9 +6584,10 @@ public SseConfiguration getBucketEncryption(GetBucketEncryptionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("encryption", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + Multimap queryParams = HashMultimap.create(); + queryParams.put("encryption", ""); + + try (Response response = executeGet(args, null, queryParams)) { return Xml.unmarshal(SseConfiguration.class, response.body().charStream()); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() @@ -6721,11 +6627,11 @@ public void deleteBucketEncryption(DeleteBucketEncryptionArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("encryption", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("encryption", ""); + try { - Response response = executeDelete(args.bucket(), "", queryParamMap); - response.close(); + executeDelete(args, null, queryParams); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.SERVER_SIDE_ENCRYPTION_CONFIGURATION_NOT_FOUND_ERROR) { @@ -6763,10 +6669,10 @@ public Tags getBucketTags(GetBucketTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); - try (Response response = executeGet(args.bucket(), null, null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { return Xml.unmarshal(Tags.class, response.body().charStream()); } catch (ErrorResponseException e) { if (e.errorResponse().errorCode() != ErrorCode.NO_SUCH_TAG_SET) { @@ -6808,9 +6714,10 @@ public void setBucketTags(SetBucketTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); - Response response = executePut(args.bucket(), null, null, queryParamMap, args.tags(), 0); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); + + Response response = executePut(args, null, queryParams, args.tags(), 0); response.close(); } @@ -6841,10 +6748,10 @@ public void deleteBucketTags(DeleteBucketTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); - Response response = executeDelete(args.bucket(), null, queryParamMap); - response.close(); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); + + executeDelete(args, null, queryParams); } /** @@ -6877,10 +6784,10 @@ public Tags getObjectTags(GetObjectTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); - try (Response response = executeGet(args.bucket(), args.object(), null, queryParamMap)) { + try (Response response = executeGet(args, null, queryParams)) { return Xml.unmarshal(Tags.class, response.body().charStream()); } } @@ -6920,10 +6827,10 @@ public void setObjectTags(SetObjectTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); - Response response = - executePut(args.bucket(), args.object(), null, queryParamMap, args.tags(), 0); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); + + Response response = executePut(args, null, queryParams, args.tags(), 0); response.close(); } @@ -6955,10 +6862,10 @@ public void deleteObjectTags(DeleteObjectTagsArgs args) XmlParserException { checkArgs(args); - Map queryParamMap = new HashMap<>(); - queryParamMap.put("tagging", ""); - Response response = executeDelete(args.bucket(), args.object(), queryParamMap); - response.close(); + Multimap queryParams = HashMultimap.create(); + queryParams.put("tagging", ""); + + executeDelete(args, null, queryParams); } private long getAvailableSize(Object data, long expectedReadSize) @@ -7250,9 +7157,20 @@ protected void abortMultipartUpload(String bucketName, String objectName, String throws InvalidBucketNameException, IllegalArgumentException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { - Map queryParamMap = new HashMap<>(); - queryParamMap.put(UPLOAD_ID, uploadId); - executeDelete(bucketName, objectName, queryParamMap); + Multimap queryParams = HashMultimap.create(); + queryParams.put(UPLOAD_ID, uploadId); + + Response response = + execute( + Method.DELETE, + bucketName, + objectName, + getRegion(bucketName, this.region), + null, + queryParams, + null, + 0); + response.close(); } /** @@ -7331,7 +7249,7 @@ protected ObjectWriteResponse completeMultipartUpload( Method.POST, bucketName, objectName, - (region != null) ? region : getRegion(bucketName), + getRegion(bucketName, region), extraHeaders, queryParams, new CompleteMultipartUpload(parts), @@ -7405,11 +7323,7 @@ protected String createMultipartUpload( InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { return createMultipartUpload( - bucketName, - getRegion(bucketName), - objectName, - Multimaps.forMap(normalizeHeaders(headerMap)), - null); + bucketName, getRegion(bucketName, null), objectName, Multimaps.forMap(headerMap), null); } /** @@ -7463,7 +7377,7 @@ protected String createMultipartUpload( Method.POST, bucketName, objectName, - (region != null) ? region : getRegion(bucketName), + getRegion(bucketName, region), headersCopy, queryParams, null, @@ -7500,17 +7414,25 @@ protected DeleteResult deleteObjects( throws InvalidBucketNameException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { - Map queryParams = new HashMap<>(); + Multimap queryParams = HashMultimap.create(); queryParams.put("delete", ""); - Map headers = null; + Multimap headers = null; if (bypassGovernanceMode) { - headers = new HashMap<>(); + headers = HashMultimap.create(); headers.put("x-amz-bypass-governance-retention", "true"); } - DeleteRequest request = new DeleteRequest(objectList, quiet); - try (Response response = executePost(bucketName, null, headers, queryParams, request)) { + try (Response response = + execute( + Method.POST, + bucketName, + null, + getRegion(bucketName, null), + headers, + queryParams, + new DeleteRequest(objectList, quiet), + 0)) { String bodyContent = new String(response.body().bytes(), StandardCharsets.UTF_8); try { if (Xml.validate(DeleteError.class, bodyContent)) { @@ -7579,7 +7501,7 @@ protected ListBucketResultV2 listObjectsV2( Method.GET, bucketName, null, - (region == null) ? getRegion(bucketName) : region, + getRegion(bucketName, region), extraHeaders, queryParams, null, @@ -7616,7 +7538,7 @@ protected ListBucketResultV1 listObjectsV1( Method.GET, bucketName, null, - (region == null) ? getRegion(bucketName) : region, + getRegion(bucketName, region), extraHeaders, queryParams, null, @@ -7658,7 +7580,7 @@ protected ListVersionsResult listObjectVersions( Method.GET, bucketName, null, - (region == null) ? getRegion(bucketName) : region, + getRegion(bucketName, region), extraHeaders, queryParams, null, @@ -7754,7 +7676,7 @@ protected ObjectWriteResponse putObject( Method.PUT, bucketName, objectName, - (region != null) ? region : getRegion(bucketName), + getRegion(bucketName, region), headers, extraQueryParams, data, @@ -7803,37 +7725,39 @@ protected ListMultipartUploadsResult listMultipartUploads( throws InvalidBucketNameException, IllegalArgumentException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { - Map queryParamMap = new HashMap<>(); - queryParamMap.put("uploads", ""); + Multimap queryParams = HashMultimap.create(); + queryParams.put("uploads", ""); if (delimiter != null) { - queryParamMap.put("delimiter", delimiter); + queryParams.put("delimiter", delimiter); } else { - queryParamMap.put("delimiter", ""); + queryParams.put("delimiter", ""); } if (keyMarker != null) { - queryParamMap.put("key-marker", keyMarker); + queryParams.put("key-marker", keyMarker); } if (maxUploads != null) { - queryParamMap.put("max-uploads", Integer.toString(maxUploads)); + queryParams.put("max-uploads", Integer.toString(maxUploads)); } if (prefix != null) { - queryParamMap.put("prefix", prefix); + queryParams.put("prefix", prefix); } else { - queryParamMap.put("prefix", ""); + queryParams.put("prefix", ""); } if (uploadIdMarker != null) { - queryParamMap.put("upload-id-marker", uploadIdMarker); + queryParams.put("upload-id-marker", uploadIdMarker); } // Setting it as default to encode the object keys in the response - queryParamMap.put("encoding-type", "url"); + queryParams.put("encoding-type", "url"); - Response response = executeGet(bucketName, null, null, queryParamMap); + Response response = + execute( + Method.GET, bucketName, null, getRegion(bucketName, null), null, queryParams, null, 0); try (ResponseBody body = response.body()) { return Xml.unmarshal(ListMultipartUploadsResult.class, body.charStream()); @@ -7871,19 +7795,28 @@ protected ListPartsResult listParts( throws InvalidBucketNameException, IllegalArgumentException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { - Map queryParamMap = new HashMap<>(); + Multimap queryParams = HashMultimap.create(); if (maxParts != null) { - queryParamMap.put("max-parts", Integer.toString(maxParts)); + queryParams.put("max-parts", Integer.toString(maxParts)); } if (partNumberMarker != null) { - queryParamMap.put("part-number-marker", Integer.toString(partNumberMarker)); + queryParams.put("part-number-marker", Integer.toString(partNumberMarker)); } - queryParamMap.put(UPLOAD_ID, uploadId); + queryParams.put(UPLOAD_ID, uploadId); - Response response = executeGet(bucketName, objectName, null, queryParamMap); + Response response = + execute( + Method.GET, + bucketName, + objectName, + getRegion(bucketName, null), + null, + queryParams, + null, + 0); try (ResponseBody body = response.body()) { return Xml.unmarshal(ListPartsResult.class, body.charStream()); @@ -7933,13 +7866,22 @@ protected String uploadPart( "data must be BufferedInputStream, RandomAccessFile, byte[] or String"); } - Map queryParamMap = new HashMap<>(); - queryParamMap.put("partNumber", Integer.toString(partNumber)); - queryParamMap.put(UPLOAD_ID, uploadId); + Multimap queryParams = HashMultimap.create(); + queryParams.put("partNumber", Integer.toString(partNumber)); + queryParams.put(UPLOAD_ID, uploadId); - Response response = executePut(bucketName, objectName, headerMap, queryParamMap, data, length); - response.close(); - return response.header("ETag").replaceAll("\"", ""); + try (Response response = + execute( + Method.PUT, + bucketName, + objectName, + getRegion(bucketName, null), + (headerMap != null) ? Multimaps.forMap(headerMap) : null, + queryParams, + data, + length)) { + return response.header("ETag").replaceAll("\"", ""); + } } /** @@ -7951,7 +7893,7 @@ protected String uploadPart( * @param objectName Object name in the bucket. * @param uploadId Upload ID. * @param partNumber Part number. - * @param headerMap Source object definitions. + * @param headers Source object definitions. * @return String - Contains ETag. * @throws ErrorResponseException thrown to indicate S3 service returned an error response. * @throws IllegalArgumentException throws to indicate invalid argument passed. @@ -7970,23 +7912,22 @@ protected String uploadPartCopy( String objectName, String uploadId, int partNumber, - Multimap headerMap) + Multimap headers) throws InvalidBucketNameException, IllegalArgumentException, NoSuchAlgorithmException, InsufficientDataException, IOException, InvalidKeyException, ServerException, XmlParserException, ErrorResponseException, InternalException, InvalidResponseException { - Multimap queryParamMap = HashMultimap.create(); - queryParamMap.put("partNumber", Integer.toString(partNumber)); - queryParamMap.put("uploadId", uploadId); - + Multimap queryParams = HashMultimap.create(); + queryParams.put("partNumber", Integer.toString(partNumber)); + queryParams.put("uploadId", uploadId); Response response = execute( Method.PUT, bucketName, objectName, - getRegion(bucketName), - headerMap, - queryParamMap, - "", + getRegion(bucketName, null), + headers, + queryParams, + null, 0); try (ResponseBody body = response.body()) { CopyPartResult result = Xml.unmarshal(CopyPartResult.class, body.charStream()); diff --git a/api/src/test/java/io/minio/MinioClientTest.java b/api/src/test/java/io/minio/MinioClientTest.java index 462afd6f9..a63dbc1b8 100644 --- a/api/src/test/java/io/minio/MinioClientTest.java +++ b/api/src/test/java/io/minio/MinioClientTest.java @@ -20,7 +20,6 @@ import io.minio.errors.InvalidBucketNameException; import io.minio.errors.InvalidResponseException; import io.minio.errors.MinioException; -import io.minio.errors.RegionConflictException; import io.minio.http.Method; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -438,7 +437,7 @@ public void testInvalidResponse4() Assert.fail("exception should be thrown"); } - @Test(expected = RegionConflictException.class) + @Test(expected = IllegalArgumentException.class) public void testMakeBucketRegionConflicts() throws NoSuchAlgorithmException, IOException, InvalidKeyException, MinioException { MinioClient client =