From 932b738026213a7dd81b011ed0cdb8fd0b182b18 Mon Sep 17 00:00:00 2001 From: Andrew Gaul Date: Tue, 19 Jun 2012 15:20:13 -0700 Subject: [PATCH 1/4] Eliminate unlikely transient blobstore TOCTOU bug --- .../java/org/jclouds/blobstore/TransientStorageStrategy.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java index 1c011141f7..611e93ba25 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientStorageStrategy.java @@ -79,8 +79,9 @@ public class TransientStorageStrategy { } public void removeBlob(final String containerName, final String blobName) { - if (containerToBlobs.containsKey(containerName)) - containerToBlobs.get(containerName).remove(blobName); + Map map = containerToBlobs.get(containerName); + if (map != null) + map.remove(blobName); } public Iterable getBlobKeysInsideContainer(final String containerName) { From edf99657c026b657fba7b45e10a89c67cb5cec08 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 19 Jun 2012 18:01:13 -0600 Subject: [PATCH 2/4] fixed missing provider name on ninefold test --- .../ninefold/storage/NinefoldStorageClientLiveTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/providers/ninefold-storage/src/test/java/org/jclouds/ninefold/storage/NinefoldStorageClientLiveTest.java b/providers/ninefold-storage/src/test/java/org/jclouds/ninefold/storage/NinefoldStorageClientLiveTest.java index e96403d101..22dd71b8b6 100644 --- a/providers/ninefold-storage/src/test/java/org/jclouds/ninefold/storage/NinefoldStorageClientLiveTest.java +++ b/providers/ninefold-storage/src/test/java/org/jclouds/ninefold/storage/NinefoldStorageClientLiveTest.java @@ -26,7 +26,9 @@ import org.testng.annotations.Test; * * @author Adrian Cole */ -@Test(groups = "live", sequential = true, testName = "NinefoldStorageClientLiveTest") +@Test(groups = "live", singleThreaded = true, testName = "NinefoldStorageClientLiveTest") public class NinefoldStorageClientLiveTest extends AtmosClientLiveTest { - + public NinefoldStorageClientLiveTest() { + provider = "ninefold-storage"; + } } From 09d5e8add4232741e719bd5a6496295c37c2cd59 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 19 Jun 2012 18:01:38 -0600 Subject: [PATCH 3/4] consistent ordering of hardware --- .../org/jclouds/compute/domain/internal/HardwareImpl.java | 7 +++---- .../compute/domain/internal/TemplateBuilderImpl.java | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/HardwareImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/HardwareImpl.java index 717e3b0cd2..52e1bd92a1 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/HardwareImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/HardwareImpl.java @@ -19,7 +19,7 @@ package org.jclouds.compute.domain.internal; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.getCoresAndSpeed; +import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.jclouds.compute.util.ComputeServiceUtils.getSpace; import java.net.URI; @@ -104,9 +104,8 @@ public class HardwareImpl extends ComputeMetadataImpl implements Hardware { public int compareTo(ResourceMetadata that) { if (that instanceof Hardware) { Hardware thatHardware = Hardware.class.cast(that); - return ComparisonChain.start().compare(getCoresAndSpeed(this), getCoresAndSpeed(thatHardware)).compare( - this.getRam(), thatHardware.getRam()).compare(getSpace(this), getSpace(thatHardware)).compare( - getHypervisor(), thatHardware.getHypervisor()).result(); + return ComparisonChain.start().compare(getCores(this), getCores(thatHardware)).compare(this.getRam(), thatHardware.getRam()) + .compare(getSpace(this), getSpace(thatHardware)).result(); } else { return super.compareTo(that); } diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java index 63adb96371..e75fc7d58f 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java @@ -437,6 +437,7 @@ public class TemplateBuilderImpl implements TemplateBuilder { predicates.add(hypervisorPredicate); predicates.add(hardwareCoresPredicate); predicates.add(hardwareRamPredicate); + predicates.add(hardwareDiskPredicate); // looks verbose, but explicit type needed for this to compile // properly From 8311d0a4e49f5e7be41d48b511ff705b8d18a432 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 19 Jun 2012 18:02:39 -0600 Subject: [PATCH 4/4] Issue 988:Extra port added to swift url --- .../openstack/swift/SwiftApiMetadata.java | 15 +--- .../swift/SwiftKeystoneApiMetadata.java | 12 +++ .../swift/SwiftClientExpectTest.java | 73 ++++++++++++++++++ .../swift/internal/BaseSwiftExpectTest.java | 75 +++++++++++++++++++ ...arseAuthenticationResponseFromHeaders.java | 3 - .../HPCloudObjectStorageApiMetadata.java | 9 +++ 6 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientExpectTest.java create mode 100644 apis/swift/src/test/java/org/jclouds/openstack/swift/internal/BaseSwiftExpectTest.java diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java index 1b1e25bf9b..34fa5479de 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftApiMetadata.java @@ -20,17 +20,12 @@ package org.jclouds.openstack.swift; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; -import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE; -import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE; import java.net.URI; import java.util.Properties; import org.jclouds.apis.ApiMetadata; import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes; -import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; -import org.jclouds.openstack.services.ServiceType; import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule; import org.jclouds.openstack.swift.config.SwiftRestClientModule; import org.jclouds.openstack.swift.config.SwiftRestClientModule.StorageEndpointModule; @@ -69,12 +64,8 @@ public class SwiftApiMetadata extends BaseRestApiMetadata { public static Properties defaultProperties() { Properties properties = BaseRestApiMetadata.defaultProperties(); - properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); - // TODO: this doesn't actually do anything yet. - properties.setProperty(KeystoneProperties.VERSION, "2.0"); - properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.API_ACCESS_KEY_CREDENTIALS); - properties.setProperty(PROPERTY_REGIONS, "DEFAULT"); properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "X-Object-Meta-"); + properties.setProperty(PROPERTY_REGIONS, "DEFAULT"); return properties; } @@ -82,8 +73,8 @@ public class SwiftApiMetadata extends BaseRestApiMetadata { protected Builder(Class syncClient, Class asyncClient){ super(syncClient, asyncClient); id("swift") - .name("OpenStack Swift Pre-Diablo API") - .identityName("tenantName:user or user") + .name("OpenStack Swift with SwiftAuth") + .identityName("tenantId:user") .credentialName("password") .documentation(URI.create("http://api.openstack.org/")) .version("1.0") diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java index 520ae80918..803054168e 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/SwiftKeystoneApiMetadata.java @@ -19,10 +19,15 @@ package org.jclouds.openstack.swift; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE; +import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE; import java.util.Properties; import org.jclouds.apis.ApiMetadata; +import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes; +import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties; +import org.jclouds.openstack.services.ServiceType; import org.jclouds.openstack.swift.blobstore.config.SwiftBlobStoreContextModule; import org.jclouds.openstack.swift.config.SwiftKeystoneRestClientModule; import org.jclouds.openstack.swift.config.SwiftRestClientModule.KeystoneStorageEndpointModule; @@ -64,6 +69,10 @@ public class SwiftKeystoneApiMetadata extends SwiftApiMetadata { public static Properties defaultProperties() { Properties properties = SwiftApiMetadata.defaultProperties(); + properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); + // TODO: this doesn't actually do anything yet. + properties.setProperty(KeystoneProperties.VERSION, "2.0"); + properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.API_ACCESS_KEY_CREDENTIALS); properties.remove(PROPERTY_REGIONS); return properties; } @@ -72,6 +81,9 @@ public class SwiftKeystoneApiMetadata extends SwiftApiMetadata { protected Builder(){ super(SwiftKeystoneClient.class, SwiftKeystoneAsyncClient.class); id("swift-keystone") + .name("OpenStack Swift with Keystone authentication") + .identityName("tenantName:user or user") + .credentialName("password") .context(CONTEXT_TOKEN) .defaultModules(ImmutableSet.>of(KeystoneStorageEndpointModule.class, SwiftKeystoneRestClientModule.class, SwiftBlobStoreContextModule.class)); } diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientExpectTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientExpectTest.java new file mode 100644 index 0000000000..7070455160 --- /dev/null +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/SwiftClientExpectTest.java @@ -0,0 +1,73 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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; + +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import java.net.URI; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.swift.internal.BaseSwiftExpectTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; + +/** + * + * @author Adrian Cole + */ +@Test(testName = "SwiftClientExpectTest") +public class SwiftClientExpectTest extends BaseSwiftExpectTest { + + public void testContainerExistsWhenResponseIs2xxReturnsTrue() throws Exception { + HttpRequest headContainer = HttpRequest.builder() + .method("HEAD") + .endpoint(URI.create(swiftEndpointWithHostReplaced + "/foo")) + .headers( + ImmutableMultimap. builder() + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse headContainerResponse = HttpResponse.builder().statusCode(200).build(); + + SwiftClient clientWhenContainerExists = requestsSendResponses(authRequest, + authResponse, headContainer, headContainerResponse); + + assertTrue(clientWhenContainerExists.containerExists("foo")); + } + + public void testContainerExistsWhenResponseIs404ReturnsFalse() throws Exception { + HttpRequest headContainer = HttpRequest.builder() + .method("HEAD") + .endpoint(URI.create(swiftEndpointWithHostReplaced + "/foo")) + .headers( + ImmutableMultimap. builder() + .put("X-Auth-Token", authToken).build()).build(); + + HttpResponse headContainerResponse = HttpResponse.builder().statusCode(404).build(); + + SwiftClient clientWhenContainerDoesntExist = requestsSendResponses(authRequest, + authResponse, headContainer, headContainerResponse); + + assertFalse(clientWhenContainerDoesntExist.containerExists("foo")); + + } + +} diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/BaseSwiftExpectTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/BaseSwiftExpectTest.java new file mode 100644 index 0000000000..ff15a6c741 --- /dev/null +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/internal/BaseSwiftExpectTest.java @@ -0,0 +1,75 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.internal; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.rest.internal.BaseRestClientExpectTest; + +import com.google.common.collect.ImmutableMultimap; + +/** + * Base class for writing Swift Expect tests + * + * @author Adrian Cole + */ +public class BaseSwiftExpectTest extends BaseRestClientExpectTest { + + protected String endpoint = "http://myhost:8080/auth"; + protected HttpRequest authRequest; + public BaseSwiftExpectTest() { + provider = "swift"; + identity = "test:tester"; + credential = "testing"; + authRequest = HttpRequest.builder() + .method("GET") + .endpoint(URI.create(endpoint+ "/v1.0")) + .headers(ImmutableMultimap.builder() + .put("X-Auth-User", identity) + .put("X-Auth-Key", credential) + .put("Accept", "*/*") + .put("Host", "myhost:8080").build()).build(); + } + + protected String authToken = "AUTH_tk36dabe83ca744cc296a98ec46089ec35"; + + protected String swiftEndpoint = "http://127.0.0.1:8080/v1/AUTH_test"; + + /** + * often swift returns the localhost url when requested via a dns name. this + * test ensures that replacement works. + */ + protected String swiftEndpointWithHostReplaced = swiftEndpoint.replace("127.0.0.1", "myhost"); + + protected HttpResponse authResponse = HttpResponse.builder() + .statusCode(200) + .message("HTTP/1.1 200 OK") + .headers(ImmutableMultimap.builder() + .put("X-Storage-Url", swiftEndpoint) + .put("X-Auth-Token", authToken).build()).build(); + + protected Properties setupProperties() { + Properties props = super.setupProperties(); + props.put(provider+".endpoint", endpoint); + return props; + } +} \ No newline at end of file diff --git a/common/openstack/src/main/java/org/jclouds/openstack/functions/ParseAuthenticationResponseFromHeaders.java b/common/openstack/src/main/java/org/jclouds/openstack/functions/ParseAuthenticationResponseFromHeaders.java index 8061c41553..9b68139a8d 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/functions/ParseAuthenticationResponseFromHeaders.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/functions/ParseAuthenticationResponseFromHeaders.java @@ -90,9 +90,6 @@ public class ParseAuthenticationResponseFromHeaders implements Function