Skip to content

Commit

Permalink
Merge pull request #309 from mziccard/copy-request-check-target
Browse files Browse the repository at this point in the history
Update CopyRequest to check target content type
  • Loading branch information
aozarov committed Oct 30, 2015
2 parents ec10ca6 + 68b0a3d commit 33bfb1e
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ CopyRequest parse(String... args) {
if (args.length != 4) {
throw new IllegalArgumentException();
}
return CopyRequest.of(args[0], args[1], BlobInfo.builder(args[2], args[3]).build());
return CopyRequest.of(args[0], args[1], BlobId.of(args[2], args[3]));
}

@Override
Expand Down Expand Up @@ -544,11 +544,14 @@ public static void main(String... args) throws Exception {
StorageOptions.Builder optionsBuilder =
StorageOptions.builder().retryParams(RetryParams.getDefaultInstance());
StorageAction action;
String actionName;
if (args.length >= 2 && !ACTIONS.containsKey(args[0])) {
actionName = args[1];
optionsBuilder.projectId(args[0]);
action = ACTIONS.get(args[1]);
args = Arrays.copyOfRange(args, 2, args.length);
} else {
actionName = args[0];
action = ACTIONS.get(args[0]);
args = Arrays.copyOfRange(args, 1, args.length);
}
Expand All @@ -562,7 +565,7 @@ public static void main(String... args) throws Exception {
try {
request = action.parse(args);
} catch (IllegalArgumentException ex) {
System.out.println("Invalid input for action '" + args[1] + "'");
System.out.println("Invalid input for action '" + actionName + "'");
System.out.println("Expected: " + action.params());
return;
} catch (Exception ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,8 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) {
* @throws StorageException upon failure
*/
public CopyWriter copyTo(BlobId targetBlob, BlobSourceOption... options) {
BlobInfo updatedInfo = BlobInfo.builder(targetBlob).build();
CopyRequest copyRequest = CopyRequest.builder().source(info.bucket(), info.name())
.sourceOptions(convert(info, options)).target(updatedInfo).build();
.sourceOptions(convert(info, options)).target(targetBlob).build();
return storage.copy(copyRequest);
}

Expand Down Expand Up @@ -266,10 +265,7 @@ public CopyWriter copyTo(String targetBucket, BlobSourceOption... options) {
* @throws StorageException upon failure
*/
public CopyWriter copyTo(String targetBucket, String targetBlob, BlobSourceOption... options) {
BlobInfo updatedInfo = BlobInfo.builder(targetBucket, targetBlob).build();
CopyRequest copyRequest = CopyRequest.builder().source(info.bucket(), info.name())
.sourceOptions(convert(info, options)).target(updatedInfo).build();
return storage.copy(copyRequest);
return copyTo(BlobId.of(targetBucket, targetBlob), options);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,31 +551,43 @@ public Builder sourceOptions(Iterable<BlobSourceOption> options) {
}

/**
* Sets the copy target.
* Sets the copy target. Target blob information is copied from source.
*
* @return the builder.
*/
public Builder target(BlobInfo target) {
this.target = target;
public Builder target(BlobId target) {
this.target = BlobInfo.builder(target).build();
return this;
}

/**
* Sets blob's target options.
* Sets the copy target and target options. {@code target} parameter is used to override
* source blob information (e.g. {@code contentType}, {@code contentLanguage}). {@code
* target.contentType} is a required field.
*
* @return the builder.
* @throws IllegalArgumentException if {@code target.contentType} is {@code null}
*/
public Builder targetOptions(BlobTargetOption... options) {
public Builder target(BlobInfo target, BlobTargetOption... options)
throws IllegalArgumentException {
checkContentType(target);
this.target = target;
Collections.addAll(targetOptions, options);
return this;
}

/**
* Sets blob's target options.
* Sets the copy target and target options. {@code target} parameter is used to override
* source blob information (e.g. {@code contentType}, {@code contentLanguage}). {@code
* target.contentType} is a required field.
*
* @return the builder.
* @throws IllegalArgumentException if {@code target.contentType} is {@code null}
*/
public Builder targetOptions(Iterable<BlobTargetOption> options) {
public Builder target(BlobInfo target, Iterable<BlobTargetOption> options)
throws IllegalArgumentException {
checkContentType(target);
this.target = target;
Iterables.addAll(targetOptions, options);
return this;
}
Expand Down Expand Up @@ -647,27 +659,101 @@ public Long megabytesCopiedPerChunk() {
return megabytesCopiedPerChunk;
}

public static CopyRequest of(String sourceBucket, String sourceBlob, BlobInfo target) {
/**
* Creates a copy request. {@code target} parameter is used to override source blob information
* (e.g. {@code contentType}, {@code contentLanguage}). {@code target.contentType} is a required
* field.
*
* @param sourceBucket name of the bucket containing the source blob
* @param sourceBlob name of the source blob
* @param target a {@code BlobInfo} object for the target blob
* @return a copy request.
* @throws IllegalArgumentException if {@code target.contentType} is {@code null}
*/
public static CopyRequest of(String sourceBucket, String sourceBlob, BlobInfo target)
throws IllegalArgumentException {
checkContentType(target);
return builder().source(sourceBucket, sourceBlob).target(target).build();
}

public static CopyRequest of(BlobId sourceBlobId, BlobInfo target) {
/**
* Creates a copy request. {@code target} parameter is used to override source blob information
* (e.g. {@code contentType}, {@code contentLanguage}). {@code target.contentType} is a required
* field.
*
* @param sourceBlobId a {@code BlobId} object for the source blob
* @param target a {@code BlobInfo} object for the target blob
* @return a copy request.
* @throws IllegalArgumentException if {@code target.contentType} is {@code null}
*/
public static CopyRequest of(BlobId sourceBlobId, BlobInfo target)
throws IllegalArgumentException {
checkContentType(target);
return builder().source(sourceBlobId).target(target).build();
}

/**
* Creates a copy request. Target blob information is copied from source.
*
* @param sourceBucket name of the bucket containing both the source and the target blob
* @param sourceBlob name of the source blob
* @param targetBlob name of the target blob
* @return a copy request.
*/
public static CopyRequest of(String sourceBucket, String sourceBlob, String targetBlob) {
return of(sourceBucket, sourceBlob,
BlobInfo.builder(BlobId.of(sourceBucket, targetBlob)).build());
return CopyRequest.builder()
.source(sourceBucket, sourceBlob)
.target(BlobId.of(sourceBucket, targetBlob))
.build();
}

/**
* Creates a copy request. Target blob information is copied from source.
*
* @param sourceBucket name of the bucket containing the source blob
* @param sourceBlob name of the source blob
* @param target a {@code BlobId} object for the target blob
* @return a copy request.
*/
public static CopyRequest of(String sourceBucket, String sourceBlob, BlobId target) {
return builder().source(sourceBucket, sourceBlob).target(target).build();
}

/**
* Creates a copy request. Target blob information is copied from source.
*
* @param sourceBlobId a {@code BlobId} object for the source blob
* @param targetBlob name of the target blob, in the same bucket of the source blob
* @return a copy request.
*/
public static CopyRequest of(BlobId sourceBlobId, String targetBlob) {
return of(sourceBlobId,
BlobInfo.builder(BlobId.of(sourceBlobId.bucket(), targetBlob)).build());
return CopyRequest.builder()
.source(sourceBlobId)
.target(BlobId.of(sourceBlobId.bucket(), targetBlob))
.build();
}

/**
* Creates a copy request. Target blob information is copied from source.
*
* @param sourceBlobId a {@code BlobId} object for the source blob
* @param targetBlobId a {@code BlobId} object for the target blob
* @return a copy request.
*/
public static CopyRequest of(BlobId sourceBlobId, BlobId targetBlobId) {
return CopyRequest.builder()
.source(sourceBlobId)
.target(targetBlobId)
.build();
}

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

private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentException {
checkArgument(blobInfo.contentType() != null, "Blob content type can not be null");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* 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 com.google.gcloud.storage;

import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
import static org.junit.Assert.assertEquals;

import com.google.common.collect.ImmutableList;
import com.google.gcloud.storage.Storage.BlobSourceOption;
import com.google.gcloud.storage.Storage.BlobTargetOption;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class CopyRequestTest {

private static final String SOURCE_BUCKET_NAME = "b0";
private static final String SOURCE_BLOB_NAME = "o0";
private static final String TARGET_BUCKET_NAME = "b1";
private static final String TARGET_BLOB_NAME = "o1";
private static final String TARGET_BLOB_CONTENT_TYPE = "contentType";
private static final BlobId SOURCE_BLOB_ID = BlobId.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME);
private static final BlobId TARGET_BLOB_ID = BlobId.of(TARGET_BUCKET_NAME, TARGET_BLOB_NAME);
private static final BlobInfo TARGET_BLOB_INFO = BlobInfo.builder(TARGET_BLOB_ID)
.contentType(TARGET_BLOB_CONTENT_TYPE).build();

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void testCopyRequest() {
Storage.CopyRequest copyRequest1 = Storage.CopyRequest.builder()
.source(SOURCE_BLOB_ID)
.sourceOptions(BlobSourceOption.generationMatch(1))
.target(TARGET_BLOB_INFO, BlobTargetOption.predefinedAcl(PUBLIC_READ))
.build();
assertEquals(SOURCE_BLOB_ID, copyRequest1.source());
assertEquals(1, copyRequest1.sourceOptions().size());
assertEquals(BlobSourceOption.generationMatch(1), copyRequest1.sourceOptions().get(0));
assertEquals(TARGET_BLOB_INFO, copyRequest1.target());
assertEquals(1, copyRequest1.targetOptions().size());
assertEquals(BlobTargetOption.predefinedAcl(PUBLIC_READ), copyRequest1.targetOptions().get(0));

Storage.CopyRequest copyRequest2 = Storage.CopyRequest.builder()
.source(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME)
.target(TARGET_BLOB_ID)
.build();
assertEquals(SOURCE_BLOB_ID, copyRequest2.source());
assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest2.target());

Storage.CopyRequest copyRequest3 = Storage.CopyRequest.builder()
.source(SOURCE_BLOB_ID)
.target(TARGET_BLOB_INFO, ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ)))
.build();
assertEquals(SOURCE_BLOB_ID, copyRequest3.source());
assertEquals(TARGET_BLOB_INFO, copyRequest3.target());
assertEquals(ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ)),
copyRequest3.targetOptions());
}

@Test
public void testCopyRequestOf() {
Storage.CopyRequest copyRequest1 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_INFO);
assertEquals(SOURCE_BLOB_ID, copyRequest1.source());
assertEquals(TARGET_BLOB_INFO, copyRequest1.target());

Storage.CopyRequest copyRequest2 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_NAME);
assertEquals(SOURCE_BLOB_ID, copyRequest2.source());
assertEquals(BlobInfo.builder(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME).build(),
copyRequest2.target());

Storage.CopyRequest copyRequest3 =
Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_INFO);
assertEquals(SOURCE_BLOB_ID, copyRequest3.source());
assertEquals(TARGET_BLOB_INFO, copyRequest3.target());

Storage.CopyRequest copyRequest4 =
Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_NAME);
assertEquals(SOURCE_BLOB_ID, copyRequest4.source());
assertEquals(BlobInfo.builder(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME).build(),
copyRequest4.target());

Storage.CopyRequest copyRequest5 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_ID);
assertEquals(SOURCE_BLOB_ID, copyRequest5.source());
assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest5.target());

Storage.CopyRequest copyRequest6 =
Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_ID);
assertEquals(SOURCE_BLOB_ID, copyRequest6.source());
assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest6.target());
}

@Test
public void testCopyRequestFail() {
thrown.expect(IllegalArgumentException.class);
Storage.CopyRequest.builder()
.source(SOURCE_BLOB_ID)
.target(BlobInfo.builder(TARGET_BLOB_ID).build())
.build();
}

@Test
public void testCopyRequestOfBlobInfoFail() {
thrown.expect(IllegalArgumentException.class);
Storage.CopyRequest.of(SOURCE_BLOB_ID, BlobInfo.builder(TARGET_BLOB_ID).build());
}

@Test
public void testCopyRequestOfStringFail() {
thrown.expect(IllegalArgumentException.class);
Storage.CopyRequest.of(
SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, BlobInfo.builder(TARGET_BLOB_ID).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,7 @@ public void testCopyBlob() {
.build();
assertNotNull(storage.create(blob, BLOB_BYTE_CONTENT));
String targetBlobName = "test-copy-blob-target";
BlobInfo target = BlobInfo.builder(BUCKET, targetBlobName).build();
Storage.CopyRequest req = Storage.CopyRequest.of(source, target);
Storage.CopyRequest req = Storage.CopyRequest.of(source, BlobId.of(BUCKET, targetBlobName));
CopyWriter copyWriter = storage.copy(req);
assertEquals(BUCKET, copyWriter.result().bucket());
assertEquals(targetBlobName, copyWriter.result().name());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ public void testComposeWithOptions() {

@Test
public void testCopy() {
CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2);
CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId());
StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(),
EMPTY_RPC_OPTIONS, request.target().toPb(), EMPTY_RPC_OPTIONS, null);
StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L,
Expand All @@ -610,8 +610,7 @@ public void testCopyWithOptions() {
CopyRequest request = Storage.CopyRequest.builder()
.source(BLOB_INFO2.blobId())
.sourceOptions(BLOB_SOURCE_GENERATION, BLOB_SOURCE_METAGENERATION)
.target(BLOB_INFO1)
.targetOptions(BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION)
.target(BLOB_INFO1, BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION)
.build();
StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(),
BLOB_SOURCE_OPTIONS_COPY, request.target().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null);
Expand All @@ -628,7 +627,7 @@ public void testCopyWithOptions() {

@Test
public void testCopyMultipleRequests() {
CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2);
CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId());
StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(),
EMPTY_RPC_OPTIONS, request.target().toPb(), EMPTY_RPC_OPTIONS, null);
StorageRpc.RewriteResponse rpcResponse1 = new StorageRpc.RewriteResponse(rpcRequest, null, 42L,
Expand Down

0 comments on commit 33bfb1e

Please sign in to comment.