mirror of https://github.com/apache/jclouds.git
Adds a rackspace-specific test and a fix for the volume-attach extension problem.
This commit is contained in:
parent
3077a0cc7c
commit
8217248571
|
@ -112,18 +112,11 @@ public class VolumePredicates {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Volume volume) {
|
public boolean apply(Volume volume) {
|
||||||
checkNotNull(volume, "volume must be defined");
|
checkNotNull(volume, "volume must be defined");
|
||||||
|
|
||||||
if (status.equals(volume.getStatus())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Volume volumeUpdated = volumeApi.get(volume.getId());
|
Volume volumeUpdated = volumeApi.get(volume.getId());
|
||||||
checkNotNull(volumeUpdated, "Volume %s not found.", volume.getId());
|
checkNotNull(volumeUpdated, "Volume %s not found.", volume.getId());
|
||||||
|
|
||||||
return status.equals(volumeUpdated.getStatus());
|
return status.equals(volumeUpdated.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static class DeletedPredicate implements Predicate<Volume> {
|
private static class DeletedPredicate implements Predicate<Volume> {
|
||||||
private VolumeApi volumeApi;
|
private VolumeApi volumeApi;
|
||||||
|
|
|
@ -16,8 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v2_0.extensions;
|
package org.jclouds.openstack.nova.v2_0.extensions;
|
||||||
|
|
||||||
import com.google.common.collect.FluentIterable;
|
import static org.testng.Assert.assertEquals;
|
||||||
import com.google.common.collect.Iterables;
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.jclouds.ContextBuilder;
|
import org.jclouds.ContextBuilder;
|
||||||
import org.jclouds.openstack.cinder.v1.CinderApi;
|
import org.jclouds.openstack.cinder.v1.CinderApi;
|
||||||
import org.jclouds.openstack.cinder.v1.domain.Volume;
|
import org.jclouds.openstack.cinder.v1.domain.Volume;
|
||||||
|
@ -31,10 +35,7 @@ import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.util.concurrent.TimeoutException;
|
import com.google.common.collect.FluentIterable;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of Volume Attachment API
|
* Tests behavior of Volume Attachment API
|
||||||
|
@ -44,10 +45,22 @@ public class VolumeAttachmentApiLiveTest extends BaseNovaApiLiveTest {
|
||||||
private VolumeApi volumeApi;
|
private VolumeApi volumeApi;
|
||||||
private VolumeAttachmentApi volumeAttachmentApi;
|
private VolumeAttachmentApi volumeAttachmentApi;
|
||||||
|
|
||||||
private String region;
|
|
||||||
private Volume volume;
|
private Volume volume;
|
||||||
private Server server;
|
private Server server;
|
||||||
|
|
||||||
|
protected String volumeProvider;
|
||||||
|
protected int volumeSizeGB;
|
||||||
|
protected String deviceId = "/dev/wtf";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties props = super.setupProperties();
|
||||||
|
volumeProvider = setIfTestSystemPropertyPresent(props, provider + ".volume-provider", "openstack-cinder");
|
||||||
|
volumeSizeGB = Integer.parseInt(setIfTestSystemPropertyPresent(props, provider + ".volume-size-gb", "1"));
|
||||||
|
singleRegion = setIfTestSystemPropertyPresent(props, provider + ".region", "RegionOne");
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeClass(groups = {"integration", "live"})
|
@BeforeClass(groups = {"integration", "live"})
|
||||||
@Override
|
@Override
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
@ -55,67 +68,44 @@ public class VolumeAttachmentApiLiveTest extends BaseNovaApiLiveTest {
|
||||||
|
|
||||||
CinderApi cinderApi;
|
CinderApi cinderApi;
|
||||||
|
|
||||||
if ("openstack-cinder".equals(getVolumeProvider())) {
|
if ("openstack-cinder".equals(volumeProvider)) {
|
||||||
cinderApi = ContextBuilder.newBuilder(getVolumeProvider())
|
cinderApi = ContextBuilder.newBuilder(volumeProvider)
|
||||||
.endpoint(endpoint)
|
.endpoint(endpoint)
|
||||||
.credentials(identity, credential)
|
.credentials(identity, credential)
|
||||||
.buildApi(CinderApi.class);
|
.buildApi(CinderApi.class);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cinderApi = ContextBuilder.newBuilder(getVolumeProvider())
|
cinderApi = ContextBuilder.newBuilder(volumeProvider)
|
||||||
.credentials(identity, credential)
|
.credentials(identity, credential)
|
||||||
.buildApi(CinderApi.class);
|
.buildApi(CinderApi.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
region = Iterables.getFirst(regions, "RegionOne");
|
volumeApi = cinderApi.getVolumeApi(singleRegion);
|
||||||
volumeApi = cinderApi.getVolumeApi(region);
|
volumeAttachmentApi = api.getVolumeAttachmentApi(singleRegion).get();
|
||||||
volumeAttachmentApi = api.getVolumeAttachmentApi(region).get();
|
|
||||||
|
|
||||||
CreateVolumeOptions options = CreateVolumeOptions.Builder
|
CreateVolumeOptions options = CreateVolumeOptions.Builder
|
||||||
.name("jclouds-test-volume")
|
.name("jclouds-test-volume")
|
||||||
.description("description of test volume");
|
.description("description of test volume");
|
||||||
|
|
||||||
volume = volumeApi.create(getVolumeSizeGB(), options);
|
volume = volumeApi.create(volumeSizeGB, options);
|
||||||
VolumePredicates.awaitAvailable(volumeApi).apply(volume);
|
VolumePredicates.awaitAvailable(volumeApi).apply(volume);
|
||||||
|
|
||||||
server = createServerInRegion(region);
|
server = createServerInRegion(singleRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass(groups = {"integration", "live"})
|
@AfterClass(groups = {"integration", "live"})
|
||||||
@Override
|
@Override
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
volumeApi.delete(volume.getId());
|
volumeApi.delete(volume.getId());
|
||||||
api.getServerApi(region).delete(server.getId());
|
api.getServerApi(singleRegion).delete(server.getId());
|
||||||
|
|
||||||
super.tearDown();
|
super.tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVolumeProvider() {
|
|
||||||
String volumeProviderKey = "test." + provider + ".volume-provider";
|
|
||||||
|
|
||||||
if (System.getProperties().containsKey(volumeProviderKey)) {
|
|
||||||
return System.getProperty(volumeProviderKey);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return "openstack-cinder";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVolumeSizeGB() {
|
|
||||||
String volumeSizeKey = "test." + provider + ".volume-size-gb";
|
|
||||||
|
|
||||||
if (System.getProperties().containsKey(volumeSizeKey)) {
|
|
||||||
return Integer.parseInt(System.getProperty(volumeSizeKey));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAttachVolume() throws TimeoutException {
|
public void testAttachVolume() throws TimeoutException {
|
||||||
VolumeAttachment volumeAttachment = volumeAttachmentApi
|
VolumeAttachment volumeAttachment = volumeAttachmentApi
|
||||||
.attachVolumeToServerAsDevice(volume.getId(), server.getId(), "/dev/wtf");
|
.attachVolumeToServerAsDevice(volume.getId(), server.getId(), deviceId);
|
||||||
|
|
||||||
// Wait for the volume to become Attached (aka In Use) before moving on
|
// Wait for the volume to become Attached (aka In Use) before moving on
|
||||||
if (!VolumePredicates.awaitInUse(volumeApi).apply(volume)) {
|
if (!VolumePredicates.awaitInUse(volumeApi).apply(volume)) {
|
||||||
|
|
|
@ -54,16 +54,15 @@ public class BaseNovaApiLiveTest extends BaseApiLiveTest<NovaApi> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Set<String> regions;
|
protected Set<String> regions;
|
||||||
|
protected String singleRegion;
|
||||||
|
|
||||||
@BeforeClass(groups = { "integration", "live" })
|
@BeforeClass(groups = { "integration", "live" })
|
||||||
@Override
|
@Override
|
||||||
public void setup() {
|
public void setup() {
|
||||||
super.setup();
|
super.setup();
|
||||||
|
|
||||||
String testRegion = System.getProperty("test." + provider + ".region");
|
if (singleRegion != null) {
|
||||||
|
regions = ImmutableSet.of(singleRegion);
|
||||||
if (testRegion != null) {
|
|
||||||
regions = ImmutableSet.of(testRegion);
|
|
||||||
} else {
|
} else {
|
||||||
regions = api.getConfiguredRegions();
|
regions = api.getConfiguredRegions();
|
||||||
}
|
}
|
||||||
|
@ -82,6 +81,7 @@ public class BaseNovaApiLiveTest extends BaseApiLiveTest<NovaApi> {
|
||||||
Properties props = super.setupProperties();
|
Properties props = super.setupProperties();
|
||||||
setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
|
setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
|
||||||
setIfTestSystemPropertyPresent(props, NovaProperties.AUTO_ALLOCATE_FLOATING_IPS);
|
setIfTestSystemPropertyPresent(props, NovaProperties.AUTO_ALLOCATE_FLOATING_IPS);
|
||||||
|
singleRegion = setIfTestSystemPropertyPresent(props, provider + ".region");
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,17 @@ public abstract class BaseApiLiveTest<A extends Closeable> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String setIfTestSystemPropertyPresent(Properties overrides, String key, String defaultValue) {
|
||||||
|
String val = setIfTestSystemPropertyPresent(overrides, key);
|
||||||
|
|
||||||
|
if (val == null) {
|
||||||
|
val = defaultValue;
|
||||||
|
overrides.setProperty(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This helps live testing against specific regions only.
|
* This helps live testing against specific regions only.
|
||||||
* @param regions A list of regions, usually from getConfiguredRegions()
|
* @param regions A list of regions, usually from getConfiguredRegions()
|
||||||
|
|
|
@ -110,6 +110,12 @@
|
||||||
<artifactId>auto-service</artifactId>
|
<artifactId>auto-service</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jclouds.provider</groupId>
|
||||||
|
<artifactId>rackspace-cloudblockstorage-us</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
|
||||||
import org.jclouds.openstack.nova.v2_0.NovaApiMetadata;
|
import org.jclouds.openstack.nova.v2_0.NovaApiMetadata;
|
||||||
import org.jclouds.openstack.nova.v2_0.config.NovaHttpApiModule;
|
|
||||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
import org.jclouds.providers.internal.BaseProviderMetadata;
|
import org.jclouds.providers.internal.BaseProviderMetadata;
|
||||||
|
@ -35,6 +34,7 @@ import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticati
|
||||||
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
|
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
|
||||||
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
|
import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
|
||||||
import org.jclouds.rackspace.cloudservers.us.config.CloudServersUSComputeServiceContextModule;
|
import org.jclouds.rackspace.cloudservers.us.config.CloudServersUSComputeServiceContextModule;
|
||||||
|
import org.jclouds.rackspace.cloudservers.us.config.CloudServersUSHttpApiModule;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -87,13 +87,14 @@ public class CloudServersUSProviderMetadata extends BaseProviderMetadata {
|
||||||
.version("2")
|
.version("2")
|
||||||
.defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
|
.defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
|
||||||
.endpointName("identity service url ending in /v2.0/")
|
.endpointName("identity service url ending in /v2.0/")
|
||||||
.documentation(URI.create("http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/index.html"))
|
.documentation(
|
||||||
|
URI.create("http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/index.html"))
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
|
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
|
||||||
.add(CloudIdentityAuthenticationApiModule.class)
|
.add(CloudIdentityAuthenticationApiModule.class)
|
||||||
.add(CloudIdentityAuthenticationModule.class)
|
.add(CloudIdentityAuthenticationModule.class)
|
||||||
.add(RegionModule.class)
|
.add(RegionModule.class)
|
||||||
.add(NovaParserModule.class)
|
.add(NovaParserModule.class)
|
||||||
.add(NovaHttpApiModule.class)
|
.add(CloudServersUSHttpApiModule.class)
|
||||||
.add(CloudServersUSComputeServiceContextModule.class).build())
|
.add(CloudServersUSComputeServiceContextModule.class).build())
|
||||||
.build())
|
.build())
|
||||||
.homepage(URI.create("http://www.rackspace.com/cloud/nextgen"))
|
.homepage(URI.create("http://www.rackspace.com/cloud/nextgen"))
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* 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.rackspace.cloudservers.us.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler;
|
||||||
|
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||||
|
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||||
|
import org.jclouds.rest.ConfiguresHttpApi;
|
||||||
|
import org.jclouds.rest.config.HttpApiModule;
|
||||||
|
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the Rackspace connection.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ConfiguresHttpApi
|
||||||
|
public class CloudServersUSHttpApiModule extends HttpApiModule<NovaApi> {
|
||||||
|
|
||||||
|
public CloudServersUSHttpApiModule() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public Multimap<URI, URI> aliases() {
|
||||||
|
return ImmutableMultimap.<URI, URI>builder()
|
||||||
|
.put(URI.create(ExtensionNamespaces.SECURITY_GROUPS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.FLOATING_IPS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.KEYPAIRS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.HOSTS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.VOLUMES),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.ADMIN_ACTIONS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/admin-actions/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.AGGREGATES),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/aggregates/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.FLAVOR_EXTRA_SPECS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/flavor_extra_specs/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.QUOTAS),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.VOLUME_TYPES),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.AVAILABILITY_ZONE),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/availabilityzone/api/v1.1"))
|
||||||
|
/**
|
||||||
|
* Only change - this is to ensure that for rackspace, the extension detection for
|
||||||
|
* VOLUME_ATTACHMENTS is based on discovering this namespace (VOLUMES).
|
||||||
|
*/
|
||||||
|
.put(URI.create(ExtensionNamespaces.VOLUME_ATTACHMENTS),
|
||||||
|
//URI.create("http://docs.openstack.org/compute/ext/os-volume-attachment-update/api/v2"))
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
||||||
|
.put(URI.create(ExtensionNamespaces.ATTACH_INTERFACES),
|
||||||
|
URI.create("http://docs.openstack.org/compute/ext/interfaces/api/v1.1"))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByRegion(final Provider<NovaApi> novaApi) {
|
||||||
|
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||||
|
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||||
|
@Override
|
||||||
|
public Set<? extends Extension> load(String key) throws Exception {
|
||||||
|
return novaApi.get().getExtensionApi(key).list();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindErrorHandlers() {
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(NovaErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(NovaErrorHandler.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(NovaErrorHandler.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* 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.rackspace.cloudservers.us.compute.extensions;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAttachmentApiLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test(groups = "live", singleThreaded = true, testName = "CloudServersUSVolumeAttachmentExtensionLivetest")
|
||||||
|
public class CloudServersUSVolumeAttachmentExtensionLiveTest extends VolumeAttachmentApiLiveTest {
|
||||||
|
|
||||||
|
public CloudServersUSVolumeAttachmentExtensionLiveTest() {
|
||||||
|
provider = "rackspace-cloudservers-us";
|
||||||
|
// Specifying a device currently does not work for rackspace and causes issues
|
||||||
|
deviceId = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties props = super.setupProperties();
|
||||||
|
volumeProvider = "rackspace-cloudblockstorage-us";
|
||||||
|
volumeSizeGB = 80;
|
||||||
|
singleRegion = "IAD";
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue