Skip to content

Commit

Permalink
Add builder support to Compose object api (#979)
Browse files Browse the repository at this point in the history
  • Loading branch information
sinhaashish authored Jun 22, 2020
1 parent 2b8f831 commit 0014bf3
Show file tree
Hide file tree
Showing 8 changed files with 642 additions and 583 deletions.
6 changes: 6 additions & 0 deletions api/src/main/java/io/minio/BaseArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ protected void validateNullOrNotEmptyString(String arg, String argName) {
}
}

protected void validateNullOrPositive(Number arg, String argName) {
if (arg != null && arg.longValue() < 0) {
throw new IllegalArgumentException(argName + " cannot be non-negative.");
}
}

public Builder() {
this.operations = new ArrayList<>();
}
Expand Down
51 changes: 51 additions & 0 deletions api/src/main/java/io/minio/ComposeObjectArgs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage, (C) 2020 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.minio;

import java.util.List;

public class ComposeObjectArgs extends ObjectWriteArgs {
List<ComposeSource> sources;

public List<ComposeSource> sources() {
return sources;
}

public static Builder builder() {
return new Builder();
}

public static final class Builder extends ObjectWriteArgs.Builder<Builder, ComposeObjectArgs> {
@Override
protected void validate(ComposeObjectArgs args) {
super.validate(args);
validateSources(args.sources);
}

public Builder sources(List<ComposeSource> sources) {
validateSources(sources);
operations.add(args -> args.sources = sources);
return this;
}

private void validateSources(List<ComposeSource> sources) {
if (sources == null || sources.isEmpty()) {
throw new IllegalArgumentException("compose sources cannot be empty");
}
}
}
}
220 changes: 108 additions & 112 deletions api/src/main/java/io/minio/ComposeSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,105 +17,109 @@

package io.minio;

import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.time.ZonedDateTime;
import okhttp3.HttpUrl;

/** Source information to compose object. */
public class ComposeSource {
private String bucketName;
private String objectName;
public class ComposeSource extends ObjectVersionArgs {
private Long offset;
private Long length;
private Map<String, String> headerMap;
private CopyConditions copyConditions;
private ServerSideEncryptionCustomerKey ssec;
private long objectSize;
private Map<String, String> headers;
private String matchETag;
private String notMatchETag;
private ZonedDateTime modifiedSince;
private ZonedDateTime unmodifiedSince;
private ServerSideEncryptionCustomerKey ssec;

private Multimap<String, String> headers;

/** Create new ComposeSource for given bucket and object. */
public ComposeSource(String bucketName, String objectName) throws IllegalArgumentException {
this(bucketName, objectName, null, null, null, null, null);
public Long offset() {
return offset;
}

/** Create new ComposeSource for given bucket, object, offset and length. */
public ComposeSource(String bucketName, String objectName, Long offset, Long length)
throws IllegalArgumentException {
this(bucketName, objectName, offset, length, null, null, null);
public Long length() {
return length;
}

/** Create new ComposeSource for given bucket, object, offset, length and headerMap. */
public ComposeSource(
String bucketName, String objectName, Long offset, Long length, Map<String, String> headerMap)
throws IllegalArgumentException {
this(bucketName, objectName, offset, length, headerMap, null, null);
public long objectSize() {
return objectSize;
}

/**
* Create new ComposeSource for given bucket, object, offset, length, headerMap and
* CopyConditions.
*/
public ComposeSource(
String bucketName,
String objectName,
Long offset,
Long length,
Map<String, String> headerMap,
CopyConditions copyConditions)
throws IllegalArgumentException {
this(bucketName, objectName, offset, length, headerMap, copyConditions, null);
public String matchETag() {
return matchETag;
}

/**
* Creates new ComposeSource for given bucket, object, offset, length, headerMap, CopyConditions
* and server side encryption.
*
* @throws IllegalArgumentException upon invalid value is passed to a method.
*/
public ComposeSource(
String bucketName,
String objectName,
Long offset,
Long length,
Map<String, String> headerMap,
CopyConditions copyConditions,
ServerSideEncryptionCustomerKey ssec)
throws IllegalArgumentException {
if (bucketName == null) {
throw new IllegalArgumentException("Source bucket name cannot be empty");
public String notMatchETag() {
return notMatchETag;
}

public ZonedDateTime modifiedSince() {
return modifiedSince;
}

public ZonedDateTime unmodifiedSince() {
return unmodifiedSince;
}

public Multimap<String, String> headers() {
return headers;
}

public ServerSideEncryptionCustomerKey ssec() {
return ssec;
}

public void validateSse(HttpUrl url) {
checkSse(ssec, url);
}

public static Builder builder() {
return new Builder();
}

/** Constructs header. */
public void buildHeaders(long objectSize, String etag) throws IllegalArgumentException {
validateSize(objectSize);
Multimap<String, String> headers = HashMultimap.create();
headers.put("x-amz-copy-source", S3Escaper.encodePath(bucketName + "/" + objectName));
headers.put("x-amz-copy-source-if-match", etag);

if (extraHeaders() != null) {
headers.putAll(extraHeaders());
}

if (objectName == null) {
throw new IllegalArgumentException("Source object name cannot be empty");
if (matchETag != null) {
headers.put("x-amz-copy-source-if-match", matchETag);
}

if (offset != null && offset < 0) {
throw new IllegalArgumentException("Offset cannot be negative");
if (ssec != null) {
headers.putAll(Multimaps.forMap(ssec.copySourceHeaders()));
}

if (length != null && length < 0) {
throw new IllegalArgumentException("Length cannot be negative");
if (notMatchETag != null) {
headers.put("x-amz-copy-source-if-none-match", notMatchETag);
}

if (length != null && offset == null) {
offset = 0L;
if (modifiedSince != null) {
headers.put(
"x-amz-copy-source-if-modified-since",
modifiedSince.format(Time.HTTP_HEADER_DATE_FORMAT));
}

this.bucketName = bucketName;
this.objectName = objectName;
this.offset = offset;
this.length = length;
if (headerMap != null) {
this.headerMap = Collections.unmodifiableMap(headerMap);
} else {
this.headerMap = null;
if (unmodifiedSince != null) {
headers.put(
"x-amz-copy-source-if-unmodified-since",
unmodifiedSince.format(Time.HTTP_HEADER_DATE_FORMAT));
}
this.copyConditions = copyConditions;
this.ssec = ssec;

this.objectSize = objectSize;
this.headers = headers;
}

/** Constructs header . */
public void buildHeaders(long objectSize, String etag) throws IllegalArgumentException {
private void validateSize(long objectSize) throws IllegalArgumentException {
if (offset != null && offset >= objectSize) {
throw new IllegalArgumentException(
"source "
Expand Down Expand Up @@ -153,56 +157,48 @@ public void buildHeaders(long objectSize, String etag) throws IllegalArgumentExc
+ objectSize);
}
}
}

Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
headers.put("x-amz-copy-source", S3Escaper.encodePath(bucketName + "/" + objectName));
headers.put("x-amz-copy-source-if-match", etag);
/** Argument builder of {@link ComposeSource}. */
public static final class Builder extends ObjectVersionArgs.Builder<Builder, ComposeSource> {

if (headerMap != null) {
headers.putAll(headerMap);
public Builder offset(long offset) {
validateNullOrPositive(offset, "offset");
operations.add(args -> args.offset = offset);
return this;
}

if (copyConditions != null) {
headers.putAll(copyConditions.getConditions());
public Builder length(long length) {
validateNullOrPositive(length, "length");
operations.add(args -> args.length = length);
return this;
}

if (ssec != null) {
headers.putAll(ssec.copySourceHeaders());
public Builder ssec(ServerSideEncryptionCustomerKey ssec) {
operations.add(args -> args.ssec = ssec);
return this;
}

this.objectSize = objectSize;
this.headers = Collections.unmodifiableMap(headers);
}

public String bucketName() {
return bucketName;
}

public String objectName() {
return objectName;
}

public Long offset() {
return offset;
}

public Long length() {
return length;
}

public CopyConditions copyConditions() {
return copyConditions;
}
public Builder matchETag(String etag) {
validateNullOrNotEmptyString(etag, "etag");
operations.add(args -> args.matchETag = etag);
return this;
}

public ServerSideEncryptionCustomerKey ssec() {
return ssec;
}
public Builder notMatchETag(String etag) {
validateNullOrNotEmptyString(etag, "etag");
operations.add(args -> args.notMatchETag = etag);
return this;
}

public Map<String, String> headers() {
return headers;
}
public Builder modifiedSince(ZonedDateTime modifiedTime) {
operations.add(args -> args.modifiedSince = modifiedTime);
return this;
}

public long objectSize() {
return objectSize;
public Builder unmodifiedSince(ZonedDateTime unmodifiedTime) {
operations.add(args -> args.unmodifiedSince = unmodifiedTime);
return this;
}
}
}
Loading

0 comments on commit 0014bf3

Please sign in to comment.