diff --git a/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java b/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java index cf0e97b924..09293550bc 100755 --- a/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java +++ b/aws/core/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java @@ -94,7 +94,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { && (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown"))) exception = new ResourceNotFoundException(message, exception); else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error - .getCode().endsWith(".Duplicate"))) || (message != null && message.indexOf("already exists") != -1)) + .getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1))) exception = new IllegalStateException(message, exception); else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) exception = new AuthorizationException(exception.getMessage(), exception); diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/ScaleUpCloudBlobStoreContextContextBuilder.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/ScaleUpCloudBlobStoreContextContextBuilder.java new file mode 100644 index 0000000000..9a433a8945 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/ScaleUpCloudBlobStoreContextContextBuilder.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 org.jclouds.aws.s3.blobstore; + +import java.util.List; +import java.util.Properties; + +import org.jclouds.aws.s3.S3ContextBuilder; +import org.jclouds.aws.s3.blobstore.config.ScaleUpCloudBlobStoreContextModule; + +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public class ScaleUpCloudBlobStoreContextContextBuilder extends S3ContextBuilder { + + public ScaleUpCloudBlobStoreContextContextBuilder(Properties props) { + super(props); + } + + @Override + protected void addContextModule(List modules) { + modules.add(new ScaleUpCloudBlobStoreContextModule()); + } + +} \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/S3BlobStoreContextModule.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/S3BlobStoreContextModule.java index 9ca1d87698..2a93fee09a 100755 --- a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/S3BlobStoreContextModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/S3BlobStoreContextModule.java @@ -29,6 +29,8 @@ import org.jclouds.aws.s3.S3Client; import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore; import org.jclouds.aws.s3.blobstore.S3BlobRequestSigner; import org.jclouds.aws.s3.blobstore.S3BlobStore; +import org.jclouds.aws.s3.blobstore.functions.LocationFromBucketLocation; +import org.jclouds.aws.s3.domain.BucketMetadata; import org.jclouds.aws.suppliers.DefaultLocationSupplier; import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobRequestSigner; @@ -43,6 +45,7 @@ import org.jclouds.domain.LocationScope; import org.jclouds.domain.internal.LocationImpl; import org.jclouds.rest.annotations.Provider; +import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.Sets; @@ -70,6 +73,12 @@ public class S3BlobStoreContextModule extends AbstractModule { bind(BlobStoreContext.class).to(new TypeLiteral>() { }).in(Scopes.SINGLETON); bind(BlobRequestSigner.class).to(S3BlobRequestSigner.class); + bindBucketLocationStrategy(); + } + + protected void bindBucketLocationStrategy() { + bind(new TypeLiteral>() { + }).to(LocationFromBucketLocation.class); } @Provides diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/ScaleUpCloudBlobStoreContextModule.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/ScaleUpCloudBlobStoreContextModule.java new file mode 100644 index 0000000000..771d3fbc2f --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/config/ScaleUpCloudBlobStoreContextModule.java @@ -0,0 +1,41 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 org.jclouds.aws.s3.blobstore.config; + +import org.jclouds.aws.s3.domain.BucketMetadata; +import org.jclouds.domain.Location; + +import com.google.common.base.Function; +import com.google.common.base.Functions; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +public class ScaleUpCloudBlobStoreContextModule extends S3BlobStoreContextModule { + + @SuppressWarnings("rawtypes") + @Override + protected void bindBucketLocationStrategy() { + bind(new TypeLiteral>() { + }).toInstance((Function)Functions.constant(null)); + } +} diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/BucketToResourceMetadata.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/BucketToResourceMetadata.java index a1a891be0b..85b33c9219 100644 --- a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/BucketToResourceMetadata.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/BucketToResourceMetadata.java @@ -19,80 +19,36 @@ package org.jclouds.aws.s3.blobstore.functions; -import java.util.NoSuchElementException; -import java.util.Set; -import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.aws.s3.S3Client; import org.jclouds.aws.s3.domain.BucketMetadata; -import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.domain.MutableStorageMetadata; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl; -import org.jclouds.collect.Memoized; import org.jclouds.domain.Location; -import org.jclouds.logging.Logger; import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.collect.Iterables; /** * @author Adrian Cole */ @Singleton public class BucketToResourceMetadata implements Function { - private final S3Client client; - private final Location onlyLocation; - private final Supplier> locations; - - @Resource - protected Logger logger = Logger.NULL; + private final Function locationOfBucket; @Inject - BucketToResourceMetadata(S3Client client, @Memoized Supplier> locations) { - this.client = client; - this.onlyLocation = locations.get().size() == 1 ? Iterables.get(locations.get(), 0) : null; - this.locations = locations; + BucketToResourceMetadata(Function locationOfBucket) { + this.locationOfBucket = locationOfBucket; } public StorageMetadata apply(BucketMetadata from) { MutableStorageMetadata to = new MutableStorageMetadataImpl(); to.setName(from.getName()); to.setType(StorageType.CONTAINER); - to.setLocation(onlyLocation != null ? onlyLocation : getLocation(from)); + to.setLocation(locationOfBucket.apply(from)); return to; } - - private Location getLocation(BucketMetadata from) { - try { - Set locations = this.locations.get(); - final String region = client.getBucketLocation(from.getName()); - assert region != null : String.format("could not get region for %s", from.getName()); - if (region != null) { - try { - return Iterables.find(locations, new Predicate() { - - @Override - public boolean apply(Location input) { - return input.getId().equalsIgnoreCase(region.toString()); - } - - }); - } catch (NoSuchElementException e) { - logger.error("could not get location for region %s in %s", region, locations); - } - } else { - logger.error("could not get region for %s", from.getName()); - } - } catch (ContainerNotFoundException e) { - logger.error(e, "could not get region for %s, as service suggests the bucket doesn't exist", from.getName()); - } - return null; - } } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/LocationFromBucketLocation.java b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/LocationFromBucketLocation.java new file mode 100644 index 0000000000..3a3c62814f --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/s3/blobstore/functions/LocationFromBucketLocation.java @@ -0,0 +1,88 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 org.jclouds.aws.s3.blobstore.functions; + +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.aws.s3.S3Client; +import org.jclouds.aws.s3.domain.BucketMetadata; +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; + +/** + * @author Adrian Cole + */ +@Singleton +public class LocationFromBucketLocation implements Function { + private final Location onlyLocation; + private final Supplier> locations; + private final S3Client client; + + @Resource + protected Logger logger = Logger.NULL; + + @Inject + LocationFromBucketLocation(S3Client client, @Memoized Supplier> locations) { + this.client = client; + this.onlyLocation = locations.get().size() == 1 ? Iterables.get(locations.get(), 0) : null; + this.locations = locations; + } + + public Location apply(BucketMetadata from) { + if (onlyLocation != null) + return onlyLocation; + try { + Set locations = this.locations.get(); + final String region = client.getBucketLocation(from.getName()); + assert region != null : String.format("could not get region for %s", from.getName()); + if (region != null) { + try { + return Iterables.find(locations, new Predicate() { + + @Override + public boolean apply(Location input) { + return input.getId().equalsIgnoreCase(region.toString()); + } + + }); + } catch (NoSuchElementException e) { + logger.error("could not get location for region %s in %s", region, locations); + } + } else { + logger.error("could not get region for %s", from.getName()); + } + } catch (ContainerNotFoundException e) { + logger.error(e, "could not get region for %s, as service suggests the bucket doesn't exist", from.getName()); + } + return null; + } +} \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/s3/functions/ReturnFalseIfBucketAlreadyOwnedByYou.java b/aws/core/src/main/java/org/jclouds/aws/s3/functions/ReturnFalseIfBucketAlreadyOwnedByYou.java index 2aa6a30213..a9512fd53e 100755 --- a/aws/core/src/main/java/org/jclouds/aws/s3/functions/ReturnFalseIfBucketAlreadyOwnedByYou.java +++ b/aws/core/src/main/java/org/jclouds/aws/s3/functions/ReturnFalseIfBucketAlreadyOwnedByYou.java @@ -19,8 +19,14 @@ package org.jclouds.aws.s3.functions; +import static com.google.common.base.Throwables.getCausalChain; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.get; +import static com.google.common.collect.Iterables.size; import static org.jclouds.util.Utils.propagateOrNull; +import java.util.List; + import javax.inject.Singleton; import org.jclouds.aws.AWSResponseException; @@ -35,11 +41,12 @@ import com.google.common.base.Function; public class ReturnFalseIfBucketAlreadyOwnedByYou implements Function { public Boolean apply(Exception from) { - if (from instanceof AWSResponseException) { - AWSResponseException responseException = (AWSResponseException) from; - if ("BucketAlreadyOwnedByYou".equals(responseException.getError().getCode())) { + List throwables = getCausalChain(from); + + Iterable matchingAWSResponseException = filter(throwables, AWSResponseException.class); + if (size(matchingAWSResponseException) >= 1 && get(matchingAWSResponseException, 0).getError() != null) { + if (get(matchingAWSResponseException, 0).getError().getCode().equals("BucketAlreadyOwnedByYou")) return false; - } } return Boolean.class.cast(propagateOrNull(from)); } diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 9108d8ad63..242414993d 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -119,6 +119,10 @@ walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder +scaleup-storage.contextbuilder=org.jclouds.aws.s3.blobstore.ScaleUpCloudBlobStoreContextContextBuilder +scaleup-storage.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder +scaleup-storage.endpoint=https://scs.scaleupstorage.com + transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder