mirror of https://github.com/apache/jclouds.git
Removes CopyObjectException in favor of jclouds-standard blobstore exceptions
This commit is contained in:
parent
6945b04243
commit
65b7bdf282
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.jclouds.openstack.swift.v1;
|
||||
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
/**
|
||||
* Thrown when an object cannot be copied.
|
||||
*
|
||||
*
|
||||
* @see {@link SwiftErrorHandler#handleError(HttpCommand, HttpResponse)}
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CopyObjectException extends ResourceNotFoundException {
|
||||
|
||||
private String sourcePath;
|
||||
private String destinationPath;
|
||||
|
||||
public CopyObjectException(String sourcePath, String destinationPath, String message) {
|
||||
super(String.format("Either the source path '%s' or the destination path '%s' was not found. " +
|
||||
"(message: %s)", sourcePath, destinationPath, message));
|
||||
this.sourcePath = sourcePath;
|
||||
this.destinationPath = destinationPath;
|
||||
}
|
||||
|
||||
public String getSourcePath() {
|
||||
return sourcePath;
|
||||
}
|
||||
|
||||
public String getDestinationPath() {
|
||||
return destinationPath;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ import javax.inject.Inject;
|
|||
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.BlobStoreContext;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobAccess;
|
||||
import org.jclouds.blobstore.domain.BlobBuilder;
|
||||
|
@ -284,6 +285,9 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
|
|||
}
|
||||
} else {
|
||||
SwiftObject metadata = api.getObjectApi(regionId, fromContainer).getWithoutBody(fromName);
|
||||
if (metadata == null) {
|
||||
throw new KeyNotFoundException(fromContainer, fromName, "Swift could not find the specified source key");
|
||||
}
|
||||
contentMetadata = metadata.getPayload().getContentMetadata();
|
||||
String contentDisposition = contentMetadata.getContentDisposition();
|
||||
if (contentDisposition != null) {
|
||||
|
@ -306,7 +310,7 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
|
|||
|
||||
boolean copied = objectApi.copy(toName, fromContainer, fromName, userMetadata, systemMetadata);
|
||||
if (!copied) {
|
||||
throw new RuntimeException("could not copy blob");
|
||||
throw new KeyNotFoundException(fromContainer, fromName, "Swift could not find the specified key");
|
||||
}
|
||||
|
||||
// TODO: Swift copy object *appends* user metadata, does not overwrite
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
|
|||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
|
||||
import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound;
|
||||
import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnKeyNotFound;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
@ -272,7 +274,7 @@ public interface ObjectApi {
|
|||
*
|
||||
* @return {@code true} if the object was successfully copied, {@code false} if not.
|
||||
*
|
||||
* @throws org.jclouds.openstack.swift.v1.CopyObjectException if the source or destination container do not exist.
|
||||
* @throws KeyNotFoundException if the source or destination container do not exist.
|
||||
*/
|
||||
@Named("object:copy")
|
||||
@PUT
|
||||
|
@ -302,13 +304,13 @@ public interface ObjectApi {
|
|||
*
|
||||
* @return {@code true} if the object was successfully copied, {@code false} if not.
|
||||
*
|
||||
* @throws org.jclouds.openstack.swift.v1.CopyObjectException if the source or destination container do not exist.
|
||||
* @throws KeyNotFoundException if the source or destination container do not exist.
|
||||
*/
|
||||
@Named("object:copy")
|
||||
@PUT
|
||||
@Path("/{destinationObject}")
|
||||
@Headers(keys = OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
|
||||
@Fallback(FalseOnContainerNotFound.class)
|
||||
@Fallback(FalseOnKeyNotFound.class)
|
||||
boolean copy(@PathParam("destinationObject") String destinationObject,
|
||||
@PathParam("sourceContainer") String sourceContainer,
|
||||
@PathParam("sourceObject") String sourceObject,
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.jclouds.http.HttpCommand;
|
|||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.openstack.swift.v1.CopyObjectException;
|
||||
import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.InsufficientResourcesException;
|
||||
|
@ -55,14 +54,7 @@ public class SwiftErrorHandler implements HttpErrorHandler {
|
|||
Exception oldException = exception;
|
||||
String sourcePath = command.getCurrentRequest().getFirstHeaderOrNull(SwiftHeaders.OBJECT_COPY_FROM);
|
||||
if (sourcePath != null) {
|
||||
// the path returned here is in the form "/v1/tenant-id/destContainer/destObject"
|
||||
String path = command.getCurrentRequest().getEndpoint().getPath();
|
||||
int startOfDestinationPath = path.lastIndexOf("/", path.lastIndexOf("/") - 1);
|
||||
// get the "/destContainer/destObject" portion of the path
|
||||
String destinationPath = path.substring(startOfDestinationPath);
|
||||
|
||||
exception = new CopyObjectException(sourcePath, destinationPath, message);
|
||||
exception.initCause(oldException);
|
||||
exception = new KeyNotFoundException(oldException);
|
||||
} else if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
||||
String path = command.getCurrentRequest().getEndpoint().getPath();
|
||||
Matcher matcher = CONTAINER_PATH.matcher(path);
|
||||
|
|
|
@ -32,9 +32,9 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.http.options.GetOptions;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.openstack.swift.v1.CopyObjectException;
|
||||
import org.jclouds.openstack.swift.v1.SwiftApi;
|
||||
import org.jclouds.openstack.swift.v1.domain.ObjectList;
|
||||
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
|
||||
|
@ -141,18 +141,17 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
|
|||
// test exception thrown on bad source name
|
||||
try {
|
||||
destApi.copy(destinationObject, badSource, sourceObjectName);
|
||||
fail("Expected CopyObjectException");
|
||||
} catch (CopyObjectException e) {
|
||||
assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObjectName);
|
||||
assertEquals(e.getDestinationPath(), destinationPath);
|
||||
}
|
||||
|
||||
} catch (KeyNotFoundException e) {
|
||||
continue;
|
||||
} finally {
|
||||
deleteAllObjectsInContainer(regionId, sourceContainer);
|
||||
containerApi.deleteIfEmpty(sourceContainer);
|
||||
|
||||
deleteAllObjectsInContainer(regionId, destinationContainer);
|
||||
containerApi.deleteIfEmpty(destinationContainer);
|
||||
}
|
||||
fail("Expected KeyNotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testCopyObjectWithMetadata() throws Exception {
|
||||
|
@ -220,18 +219,17 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
|
|||
// test exception thrown on bad source name
|
||||
try {
|
||||
destApi.copy(destinationObject, badSource, sourceObjectName);
|
||||
fail("Expected CopyObjectException");
|
||||
} catch (CopyObjectException e) {
|
||||
assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObjectName);
|
||||
assertEquals(e.getDestinationPath(), destinationPath);
|
||||
}
|
||||
|
||||
} catch (KeyNotFoundException e) {
|
||||
continue;
|
||||
} finally {
|
||||
deleteAllObjectsInContainer(regionId, sourceContainer);
|
||||
containerApi.deleteIfEmpty(sourceContainer);
|
||||
|
||||
deleteAllObjectsInContainer(regionId, destinationContainer);
|
||||
containerApi.deleteIfEmpty(destinationContainer);
|
||||
}
|
||||
fail("Expected KeyNotFoundException");
|
||||
}
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
|
|
|
@ -33,6 +33,7 @@ import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METAD
|
|||
import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_REMOVE_METADATA_PREFIX;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
|
@ -44,11 +45,11 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.payloads.ByteSourcePayload;
|
||||
import org.jclouds.openstack.swift.v1.CopyObjectException;
|
||||
import org.jclouds.openstack.swift.v1.SwiftApi;
|
||||
import org.jclouds.openstack.swift.v1.domain.ObjectList;
|
||||
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
|
||||
|
@ -485,7 +486,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = CopyObjectException.class)
|
||||
@Test(expectedExceptions = KeyNotFoundException.class)
|
||||
public void testCopyObjectFail() throws InterruptedException, IOException {
|
||||
MockWebServer server = mockOpenStackServer();
|
||||
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
|
||||
|
@ -494,7 +495,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
|
|||
|
||||
try {
|
||||
SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
|
||||
// the following line will throw the CopyObjectException
|
||||
// the following line will throw the KeyNotFoundException
|
||||
api.getObjectApi("DFW", "foo").copy("bar.txt", "bogus", "foo.txt");
|
||||
} finally {
|
||||
server.shutdown();
|
||||
|
@ -529,7 +530,6 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = CopyObjectException.class)
|
||||
public void testCopyObjectWithMetadataFail() throws Exception {
|
||||
MockWebServer server = mockOpenStackServer();
|
||||
server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
|
||||
|
@ -538,7 +538,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
|
|||
|
||||
try {
|
||||
SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
|
||||
assertTrue(api.getObjectApi("DFW", "foo")
|
||||
assertFalse(api.getObjectApi("DFW", "foo")
|
||||
.copy("bar.txt", "bar", "foo.txt", ImmutableMap.of("someUserHeader", "someUserMetadataValue"),
|
||||
ImmutableMap.of("Content-Disposition", "attachment; filename=\"fname.ext\"")));
|
||||
} finally {
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.jclouds.http.HttpCommand;
|
|||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.openstack.swift.v1.CopyObjectException;
|
||||
import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.InsufficientResourcesException;
|
||||
|
@ -55,14 +54,7 @@ public class CloudFilesErrorHandler implements HttpErrorHandler {
|
|||
Exception oldException = exception;
|
||||
String sourcePath = command.getCurrentRequest().getFirstHeaderOrNull(SwiftHeaders.OBJECT_COPY_FROM);
|
||||
if (sourcePath != null) {
|
||||
// the path returned here is in the form "/v1/tenant-id/destContainer/destObject"
|
||||
String path = command.getCurrentRequest().getEndpoint().getPath();
|
||||
int startOfDestinationPath = path.lastIndexOf("/", path.lastIndexOf("/") - 1);
|
||||
// get the "/destContainer/destObject" portion of the path
|
||||
String destinationPath = path.substring(startOfDestinationPath);
|
||||
|
||||
exception = new CopyObjectException(sourcePath, destinationPath, message);
|
||||
exception.initCause(oldException);
|
||||
exception = new KeyNotFoundException(oldException);
|
||||
} else if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
||||
String path = command.getCurrentRequest().getEndpoint().getPath();
|
||||
Matcher matcher = CONTAINER_PATH.matcher(path);
|
||||
|
|
|
@ -39,6 +39,7 @@ import javax.ws.rs.PUT;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
|
||||
import org.jclouds.blobstore.domain.PageSet;
|
||||
import org.jclouds.http.functions.ParseETagHeader;
|
||||
|
@ -328,7 +329,7 @@ public interface CommonSwiftClient extends Closeable {
|
|||
|
||||
/**
|
||||
* @return True If the object was copied
|
||||
* @throws CopyObjectException If the object was not copied
|
||||
* @throws KeyNotFoundException If the object was not copied
|
||||
* @deprecated This method will be replaced by
|
||||
* {@link org.jclouds.openstack.swift.v1.features.ObjectApi#copy()}
|
||||
*/
|
||||
|
@ -337,7 +338,7 @@ public interface CommonSwiftClient extends Closeable {
|
|||
@PUT
|
||||
@Path("/{destinationContainer}/{destinationObject}")
|
||||
@Headers(keys = OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
|
||||
@Fallback(FalseOnContainerNotFound.class)
|
||||
@Fallback(FalseOnKeyNotFound.class)
|
||||
boolean copyObject(@PathParam("sourceContainer") String sourceContainer,
|
||||
@PathParam("sourceObject") String sourceObject,
|
||||
@PathParam("destinationContainer") String destinationContainer,
|
||||
|
|
|
@ -47,9 +47,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import org.jclouds.blobstore.BlobStore;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.blobstore.KeyNotFoundException;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.domain.BlobAccess;
|
||||
import org.jclouds.blobstore.domain.BlobBuilder.PayloadBlobBuilder;
|
||||
|
@ -66,8 +66,8 @@ import org.jclouds.blobstore.strategy.internal.MultipartUploadSlicingAlgorithm;
|
|||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.encryption.internal.JCECrypto;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
import org.jclouds.io.ByteStreams2;
|
||||
import org.jclouds.io.ContentMetadataBuilder;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.io.Payloads;
|
||||
import org.jclouds.io.payloads.ByteSourcePayload;
|
||||
|
@ -90,8 +90,9 @@ import com.google.common.collect.ImmutableSet;
|
|||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -983,6 +984,29 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, expectedExceptions = {KeyNotFoundException.class})
|
||||
public void testCopy404BlobFail() throws Exception {
|
||||
BlobStore blobStore = view.getBlobStore();
|
||||
String container = getContainerName();
|
||||
try {
|
||||
blobStore.copyBlob(container, "blob", container, "blob2", CopyOptions.NONE);
|
||||
} finally {
|
||||
returnContainer(container);
|
||||
}
|
||||
}
|
||||
|
||||
@Test(groups = { "integration", "live" }, expectedExceptions = {KeyNotFoundException.class})
|
||||
public void testCopy404BlobMetaFail() throws Exception {
|
||||
BlobStore blobStore = view.getBlobStore();
|
||||
String container = getContainerName();
|
||||
try {
|
||||
blobStore.copyBlob(container, "blob", container, "blob2",
|
||||
CopyOptions.builder().userMetadata(ImmutableMap.of("x", "1")).build());
|
||||
} finally {
|
||||
returnContainer(container);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateMetadata(BlobMetadata metadata) throws IOException {
|
||||
assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata()
|
||||
.getContentType();
|
||||
|
|
Loading…
Reference in New Issue