Issue 798: merge for potential 1.3.0-rc-2
diff --git a/apis/atmos/pom.xml b/apis/atmos/pom.xml
index 7b18e5e..eab04c3 100644
--- a/apis/atmos/pom.xml
+++ b/apis/atmos/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer>
<test.atmos.endpoint>https://accesspoint.atmos.com</test.atmos.endpoint>
- <test.atmos.apiversion>1.3.0</test.atmos.apiversion>
+ <test.atmos.api-version>1.3.0</test.atmos.api-version>
+ <test.atmos.build-version></test.atmos.build-version>
<test.atmos.identity>FIXME</test.atmos.identity>
<test.atmos.credential>FIXME</test.atmos.credential>
</properties>
@@ -95,7 +96,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.atmos.endpoint>${test.atmos.endpoint}</test.atmos.endpoint>
- <test.atmos.apiversion>${test.atmos.apiversion}</test.atmos.apiversion>
+ <test.atmos.api-version>${test.atmos.api-version}</test.atmos.api-version>
+ <test.atmos.build-version>${test.atmos.build-version}</test.atmos.build-version>
<test.atmos.identity>${test.atmos.identity}</test.atmos.identity>
<test.atmos.credential>${test.atmos.credential}</test.atmos.credential>
</systemPropertyVariables>
diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosTestInitializer.java b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosTestInitializer.java
index f77aec3..1cc02f1 100644
--- a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosTestInitializer.java
+++ b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/integration/AtmosTestInitializer.java
@@ -38,10 +38,10 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
+ new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
}
}
diff --git a/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYamlStream.java b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYamlStream.java
index 9505b7f..4ad13e3 100644
--- a/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYamlStream.java
+++ b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYamlStream.java
@@ -35,9 +35,9 @@
import com.google.common.base.Function;
import com.google.common.base.Functions;
-import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
diff --git a/apis/cloudfiles/pom.xml b/apis/cloudfiles/pom.xml
index cc1fac2..0ab0549 100644
--- a/apis/cloudfiles/pom.xml
+++ b/apis/cloudfiles/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
<test.cloudfiles.endpoint>https://auth.api.rackspacecloud.com</test.cloudfiles.endpoint>
- <test.cloudfiles.apiversion>1.0</test.cloudfiles.apiversion>
+ <test.cloudfiles.api-version>1.0</test.cloudfiles.api-version>
+ <test.cloudfiles.build-version></test.cloudfiles.build-version>
<test.cloudfiles.identity>${test.rackspace.identity}</test.cloudfiles.identity>
<test.cloudfiles.credential>${test.rackspace.credential}</test.cloudfiles.credential>
</properties>
@@ -110,7 +111,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.cloudfiles.endpoint>${test.cloudfiles.endpoint}</test.cloudfiles.endpoint>
- <test.cloudfiles.apiversion>${test.cloudfiles.apiversion}</test.cloudfiles.apiversion>
+ <test.cloudfiles.api-version>${test.cloudfiles.api-version}</test.cloudfiles.api-version>
+ <test.cloudfiles.build-version>${test.cloudfiles.build-version}</test.cloudfiles.build-version>
<test.cloudfiles.identity>${test.cloudfiles.identity}</test.cloudfiles.identity>
<test.cloudfiles.credential>${test.cloudfiles.credential}</test.cloudfiles.credential>
</systemPropertyVariables>
diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/functions/PublicUriForObjectInfo.java b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/functions/PublicUriForObjectInfo.java
index aa462f0..e78b301 100644
--- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/functions/PublicUriForObjectInfo.java
+++ b/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/blobstore/functions/PublicUriForObjectInfo.java
@@ -52,6 +52,9 @@
try {
return uriBuilders.get().uri(cdnContainer.getUnchecked(from.getContainer())).path(from.getName()).replaceQuery("")
.build();
+ } catch (NullPointerException e) {
+ // nulls not permitted from cache loader
+ return null;
} catch (CacheLoader.InvalidCacheLoadException e) {
// nulls not permitted from cache loader
return null;
diff --git a/apis/cloudloadbalancers/pom.xml b/apis/cloudloadbalancers/pom.xml
index 744e6ac..f414c69 100644
--- a/apis/cloudloadbalancers/pom.xml
+++ b/apis/cloudloadbalancers/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudloadbalancers.endpoint>https://auth.api.rackspacecloud.com</test.cloudloadbalancers.endpoint>
- <test.cloudloadbalancers.apiversion>1.0</test.cloudloadbalancers.apiversion>
+ <test.cloudloadbalancers.api-version>1.0</test.cloudloadbalancers.api-version>
+ <test.cloudloadbalancers.build-version></test.cloudloadbalancers.build-version>
<test.cloudloadbalancers.identity>${test.rackspace.identity}</test.cloudloadbalancers.identity>
<test.cloudloadbalancers.credential>${test.rackspace.credential}</test.cloudloadbalancers.credential>
</properties>
@@ -96,7 +97,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudloadbalancers.endpoint>${test.cloudloadbalancers.endpoint}</test.cloudloadbalancers.endpoint>
- <test.cloudloadbalancers.apiversion>${test.cloudloadbalancers.apiversion}</test.cloudloadbalancers.apiversion>
+ <test.cloudloadbalancers.api-version>${test.cloudloadbalancers.api-version}</test.cloudloadbalancers.api-version>
+ <test.cloudloadbalancers.build-version>${test.cloudloadbalancers.build-version}</test.cloudloadbalancers.build-version>
<test.cloudloadbalancers.identity>${test.cloudloadbalancers.identity}</test.cloudloadbalancers.identity>
<test.cloudloadbalancers.credential>${test.cloudloadbalancers.credential}</test.cloudloadbalancers.credential>
</systemPropertyVariables>
diff --git a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java
index 3bd986f..b88c1f3 100644
--- a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java
+++ b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/config/CloudLoadBalancersRestClientModule.java
@@ -38,6 +38,7 @@
import org.jclouds.cloudloadbalancers.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
import org.jclouds.cloudloadbalancers.reference.RackspaceConstants;
import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@@ -51,6 +52,7 @@
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
+import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
@@ -154,4 +156,8 @@
ParseCloudLoadBalancersErrorFromHttpResponse.class);
}
+ @Override
+ protected void bindRetryHandlers() {
+ bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
+ }
}
diff --git a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java
index 68a0d1a..a07e84a 100644
--- a/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java
+++ b/apis/cloudloadbalancers/src/main/java/org/jclouds/cloudloadbalancers/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java
@@ -18,17 +18,19 @@
*/
package org.jclouds.cloudloadbalancers.loadbalancer.functions;
-import java.util.Map;
+import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
import org.jclouds.cloudloadbalancers.domain.VirtualIP;
+import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerType;
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
+import org.jclouds.location.predicates.LocationPredicates;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@@ -41,20 +43,20 @@
*/
@Singleton
public class LoadBalancerToLoadBalancerMetadata implements Function<LoadBalancer, LoadBalancerMetadata> {
- protected final Supplier<Map<String, ? extends Location>> locationMap;
+ protected final Supplier<Set<? extends Location>> locations;
protected final Supplier<Location> defaultLocationSupplier;
@Inject
public LoadBalancerToLoadBalancerMetadata(Supplier<Location> defaultLocationSupplier,
- Supplier<Map<String, ? extends Location>> locationMap) {
- this.locationMap = locationMap;
+ @Memoized Supplier<Set<? extends Location>> locations) {
+ this.locations = locations;
this.defaultLocationSupplier = defaultLocationSupplier;
}
@Override
public LoadBalancerMetadata apply(LoadBalancer input) {
- Location location = locationMap.get().get(input.getRegion());
+ Location location = Iterables.find(locations.get(), LocationPredicates.idEquals(input.getRegion()));
String id = input.getRegion() + "/" + input.getId();
// TODO Builder
diff --git a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/CloudLoadBalancersAsyncClientTest.java b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/CloudLoadBalancersAsyncClientTest.java
index 4eb292e..1c1121b 100644
--- a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/CloudLoadBalancersAsyncClientTest.java
+++ b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/CloudLoadBalancersAsyncClientTest.java
@@ -19,6 +19,11 @@
package org.jclouds.cloudloadbalancers;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
+import static org.jclouds.Constants.PROPERTY_ENDPOINT;
+import static org.jclouds.cloudloadbalancers.reference.RackspaceConstants.PROPERTY_ACCOUNT_ID;
+import static org.jclouds.cloudloadbalancers.reference.Region.DFW;
+import static org.jclouds.location.reference.LocationConstants.ENDPOINT;
+import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException;
@@ -84,9 +89,12 @@
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
- overrides.setProperty(PROPERTY_REGIONS, "US");
+ overrides.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com");
overrides.setProperty(PROPERTY_API_VERSION, "1");
- overrides.setProperty(provider + ".endpoint", "https://auth");
+ overrides.setProperty(PROPERTY_REGIONS, "DFW");
+ overrides.setProperty(PROPERTY_REGION + "." + DFW + "." + ENDPOINT, String
+ .format("https://dfw.loadbalancers.api.rackspacecloud.com/v{%s}/{%s}", PROPERTY_API_VERSION,
+ PROPERTY_ACCOUNT_ID));
overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides;
}
diff --git a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersAsyncClientTest.java b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersAsyncClientTest.java
index 2d4ccc8..05280b7 100644
--- a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersAsyncClientTest.java
+++ b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersAsyncClientTest.java
@@ -28,22 +28,34 @@
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.config.CloudLoadBalancersRestClientModule;
+import org.jclouds.cloudloadbalancers.functions.ConvertLB;
import org.jclouds.cloudloadbalancers.reference.Region;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.internal.ClassMethodArgs;
+import org.jclouds.json.config.GsonModule.DateAdapter;
+import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
+import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
+import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
+import org.jclouds.rest.internal.RestContextImpl;
import org.testng.annotations.BeforeClass;
import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import com.google.inject.util.Types;
/**
* @author Adrian Cole
@@ -57,12 +69,43 @@
protected void bindRegionsToProvider() {
bindRegionsToProvider(Regions.class);
}
+
+ //TODO: replace this with Expect test
+ @SuppressWarnings("unchecked")
+ @Override
+ protected void configure() {
+ // following from CloudLoadBalancersRestClientModule, except we are hard-coding the auth response
+ install(new OpenStackAuthenticationModule() {
+ @Override
+ protected Supplier<AuthenticationResponse> provideAuthenticationResponseSupplier(
+ final LoadingCache<String,AuthenticationResponse> cache) {
+ return Suppliers.ofInstance(new AuthenticationResponse("token", ImmutableMap.<String, URI> of()));
+ }
+ });
+ bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+ bindRegionsToProvider();
+ install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
+
+ // following from RestClientModule
+ bind(new TypeLiteral<RestContext>() {
+ }).to(
+ (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(
+ RestContextImpl.class, syncClientType, asyncClientType))).in(
+ Scopes.SINGLETON);
+ bind(TypeLiteral.get(Types.newParameterizedType(RestContext.class, syncClientType, asyncClientType))).to(
+ (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, syncClientType,
+ asyncClientType))).in(Scopes.SINGLETON);
+ bindAsyncClient();
+ bindClient();
+ bindErrorHandlers();
+ bindRetryHandlers();
+ }
static class Regions implements javax.inject.Provider<Map<String, URI>> {
@Override
public Map<String, URI> get() {
- return ImmutableMap.<String, URI> of("DFW",
- URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234"));
+ return ImmutableMap.<String, URI> of("DFW", URI
+ .create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234"));
}
}
@@ -95,8 +138,8 @@
super.setupFactory();
try {
processor.setCaller(new ClassMethodArgs(CloudLoadBalancersAsyncClient.class,
- CloudLoadBalancersAsyncClient.class.getMethod("getLoadBalancerClient", String.class),
- new Object[] { Region.DFW }));
+ CloudLoadBalancersAsyncClient.class.getMethod("getLoadBalancerClient", String.class),
+ new Object[] { Region.DFW }));
} catch (Exception e) {
Throwables.propagate(e);
}
diff --git a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersClientLiveTest.java b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersClientLiveTest.java
index a673f24..e603547 100644
--- a/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersClientLiveTest.java
+++ b/apis/cloudloadbalancers/src/test/java/org/jclouds/cloudloadbalancers/features/BaseCloudLoadBalancersClientLiveTest.java
@@ -18,12 +18,9 @@
*/
package org.jclouds.cloudloadbalancers.features;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.util.Properties;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
@@ -33,6 +30,7 @@
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
+import org.jclouds.rest.BaseRestClientLiveTest;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
@@ -47,44 +45,20 @@
*
* @author Adrian Cole
*/
-public class BaseCloudLoadBalancersClientLiveTest {
- protected String prefix = System.getProperty("user.name");
+public class BaseCloudLoadBalancersClientLiveTest extends BaseRestClientLiveTest {
+ public BaseCloudLoadBalancersClientLiveTest() {
+ provider = "cloudloadbalancers";
+ }
protected CloudLoadBalancersClient client;
protected RestContext<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> context;
- protected String provider = "cloudloadbalancers";
protected String[] regions = {};
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected Predicate<IPSocket> socketTester;
protected RetryablePredicate<LoadBalancer> loadBalancerActive;
protected RetryablePredicate<LoadBalancer> loadBalancerDeleted;
protected Injector injector;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider
- + ".identity must be set. ex. apiKey");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential must be set. ex. secretKey");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = "live")
public void setupClient() {
diff --git a/apis/cloudservers/pom.xml b/apis/cloudservers/pom.xml
index f9d6002..9abeb16 100644
--- a/apis/cloudservers/pom.xml
+++ b/apis/cloudservers/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.cloudservers.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers.endpoint>
- <test.cloudservers.apiversion>1.0</test.cloudservers.apiversion>
+ <test.cloudservers.api-version>1.0</test.cloudservers.api-version>
+ <test.cloudservers.build-version></test.cloudservers.build-version>
<test.cloudservers.identity>${test.rackspace.identity}</test.cloudservers.identity>
<test.cloudservers.credential>${test.rackspace.credential}</test.cloudservers.credential>
<test.cloudservers.image-id />
@@ -108,7 +109,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudstack.endpoint>${test.cloudstack.endpoint}</test.cloudstack.endpoint>
- <test.cloudstack.apiversion>${test.cloudstack.apiversion}</test.cloudstack.apiversion>
+ <test.cloudstack.api-version>${test.cloudstack.api-version}</test.cloudstack.api-version>
+ <test.cloudstack.build-version>${test.cloudstack.build-version}</test.cloudstack.build-version>
<test.cloudstack.identity>${test.cloudstack.identity}</test.cloudstack.identity>
<test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential>
<test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id>
diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/config/CloudServersRestClientModule.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/config/CloudServersRestClientModule.java
index c643ce3..7340bb7 100644
--- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/config/CloudServersRestClientModule.java
+++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/config/CloudServersRestClientModule.java
@@ -27,6 +27,7 @@
import org.jclouds.cloudservers.ServerManagement;
import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@@ -35,6 +36,7 @@
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
+import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
@@ -74,6 +76,11 @@
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseCloudServersErrorFromHttpResponse.class);
}
+ @Override
+ protected void bindRetryHandlers() {
+ bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
+ }
+
@Provides
@Singleton
@ServerManagement
diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersExpectTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersExpectTest.java
new file mode 100644
index 0000000..7c7a2ae
--- /dev/null
+++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersExpectTest.java
@@ -0,0 +1,81 @@
+/**
+ * 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.cloudservers;
+
+import java.net.URI;
+
+import org.jclouds.cloudservers.internal.BaseCloudServersRestClientExpectTest;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "CloudServersExpectTest")
+public class CloudServersExpectTest extends BaseCloudServersRestClientExpectTest {
+
+ HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
+ .headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-User", "identity")
+ .put("X-Auth-Key", "credential")
+ .put("Accept", "*/*").build()).build();
+
+ String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
+
+ HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
+ .headers(ImmutableMultimap.<String,String>builder()
+ .put("Server", "Apache/2.2.3 (Red Hat)")
+ .put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
+ .put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Cache-Control", "s-maxage=86399")
+ .put("Content-Type", "text/xml")
+ .put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
+ .put("X-Auth-Token", authToken)
+ .put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
+ .put("X-Storage-Token", authToken)
+ .put("Connection", "Keep-Alive")
+ .put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Content-Length", "0")
+ .build()).build();
+
+ public void deleteImageReturnsTrueOn200AndFalseOn404() {
+
+ HttpRequest deleteImage11 = HttpRequest.builder().method("DELETE").endpoint(
+ URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-Token", authToken).build()).build();
+
+ HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build();
+
+ CloudServersClient clientWhenImageExists = requestsSendResponses(initialAuth, responseWithUrls, deleteImage11, imageDeleted);
+ assert clientWhenImageExists.deleteImage(11);
+
+ HttpResponse imageNotFound = HttpResponse.builder().statusCode(404).message("HTTP/1.1 404 Not Found").build();
+
+ CloudServersClient clientWhenImageDoesntExist = requestsSendResponses(initialAuth, responseWithUrls, deleteImage11, imageNotFound);
+ assert !clientWhenImageDoesntExist.deleteImage(11);
+
+ }
+
+}
\ No newline at end of file
diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/handlers/RetryOnRenewExpectTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/handlers/RetryOnRenewExpectTest.java
new file mode 100644
index 0000000..0192555
--- /dev/null
+++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/handlers/RetryOnRenewExpectTest.java
@@ -0,0 +1,173 @@
+/**
+ * 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.cloudservers.handlers;
+
+import java.net.URI;
+
+import org.jclouds.cloudservers.CloudServersClient;
+import org.jclouds.cloudservers.internal.BaseCloudServersRestClientExpectTest;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.io.Payloads;
+import org.jclouds.rest.AuthorizationException;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ * Tests behavior of {@code RetryOnRenew} handler
+ *
+ * @author grkvlt@apache.org
+ */
+@Test(groups = "unit", testName = "RetryOnRenewExpectTest")
+public class RetryOnRenewExpectTest extends BaseCloudServersRestClientExpectTest {
+
+ @Test
+ public void testShouldReauthenticateOn401() {
+ String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
+ String authToken2 = "12345678-9012-47c0-9770-2c5097da25fc";
+
+ HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
+ .headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-User", "identity")
+ .put("X-Auth-Key", "credential")
+ .put("Accept", "*/*").build()).build();
+
+
+ HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
+ .headers(ImmutableMultimap.<String,String>builder()
+ .put("Server", "Apache/2.2.3 (Red Hat)")
+ .put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
+ .put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Cache-Control", "s-maxage=86399")
+ .put("Content-Type", "text/xml")
+ .put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
+ .put("X-Auth-Token", authToken)
+ .put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
+ .put("X-Storage-Token", authToken)
+ .put("Connection", "Keep-Alive")
+ .put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Content-Length", "0")
+ .build()).build();
+
+ HttpResponse responseWithUrls2 = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
+ .headers(ImmutableMultimap.<String,String>builder()
+ .put("Server", "Apache/2.2.3 (Red Hat)")
+ .put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
+ .put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Cache-Control", "s-maxage=86399")
+ .put("Content-Type", "text/xml")
+ .put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
+ .put("X-Auth-Token", authToken2)
+ .put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
+ .put("X-Storage-Token", authToken2)
+ .put("Connection", "Keep-Alive")
+ .put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Content-Length", "0")
+ .build()).build();
+
+ HttpRequest deleteImage = HttpRequest.builder().method("DELETE").endpoint(
+ URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-Token", authToken).build()).build();
+
+ HttpResponse pleaseRenew = HttpResponse.builder().statusCode(401)
+ .message("HTTP/1.1 401 Unauthorized")
+ .payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"Invalid authentication token. Please renew.\",\"code\":401}}]"))
+ .build();
+
+ HttpRequest deleteImage2 = HttpRequest.builder().method("DELETE").endpoint(
+ URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-Token", authToken2).build()).build();
+
+ HttpResponse imageDeleted = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content").build();
+
+ CloudServersClient clientWhenImageExists = orderedRequestsSendResponses(initialAuth, responseWithUrls,
+ deleteImage, pleaseRenew, initialAuth, responseWithUrls2, deleteImage2, imageDeleted);
+
+ assert clientWhenImageExists.deleteImage(11);
+ }
+
+ @Test(expectedExceptions=AuthorizationException.class)
+ public void testDoesNotReauthenticateOnFatal401() {
+ String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
+
+ HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
+ .headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-User", "identity")
+ .put("X-Auth-Key", "credential")
+ .put("Accept", "*/*").build()).build();
+
+
+ HttpResponse responseWithUrls = HttpResponse.builder().statusCode(204).message("HTTP/1.1 204 No Content")
+ .headers(ImmutableMultimap.<String,String>builder()
+ .put("Server", "Apache/2.2.3 (Red Hat)")
+ .put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
+ .put("X-Storage-Url", "https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Cache-Control", "s-maxage=86399")
+ .put("Content-Type", "text/xml")
+ .put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
+ .put("X-Auth-Token", authToken)
+ .put("X-Server-Management-Url","https://servers.api.rackspacecloud.com/v1.0/413274")
+ .put("X-Storage-Token", authToken)
+ .put("Connection", "Keep-Alive")
+ .put("X-CDN-Management-Url", "https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22")
+ .put("Content-Length", "0")
+ .build()).build();
+
+ HttpRequest deleteImage = HttpRequest.builder().method("DELETE").endpoint(
+ URI.create("https://servers.api.rackspacecloud.com/v1.0/413274/images/11?now=1257695648897")).headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-Token", authToken).build()).build();
+
+ HttpResponse unauthResponse = HttpResponse.builder().statusCode(401)
+ .message("HTTP/1.1 401 Unauthorized")
+ .payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"Fatal unauthorized.\",\"code\":401}}]"))
+ .build();
+
+ CloudServersClient client = orderedRequestsSendResponses(initialAuth, responseWithUrls,
+ deleteImage, unauthResponse);
+
+ client.deleteImage(11);
+ }
+
+ // FIXME stack trace shows the AuthorizationException, but it's buried inside a guice TestException
+ @Test(enabled=false, expectedExceptions=AuthorizationException.class)
+ public void testDoesNotReauthenticateOnAuthentication401() {
+ HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("https://auth/v1.0"))
+ .headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("X-Auth-User", "identity")
+ .put("X-Auth-Key", "credential")
+ .put("Accept", "*/*").build()).build();
+
+
+ HttpResponse unauthResponse = HttpResponse.builder().statusCode(401)
+ .message("HTTP/1.1 401 Unauthorized")
+ .payload(Payloads.newStringPayload("[{\"unauthorized\":{\"message\":\"A different message implying fatal.\",\"code\":401}}]"))
+ .build();
+
+ CloudServersClient client = orderedRequestsSendResponses(initialAuth, unauthResponse);
+
+ client.deleteImage(11);
+ }
+}
diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/internal/BaseCloudServersRestClientExpectTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/internal/BaseCloudServersRestClientExpectTest.java
new file mode 100644
index 0000000..94050b8
--- /dev/null
+++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/internal/BaseCloudServersRestClientExpectTest.java
@@ -0,0 +1,96 @@
+/**
+ * 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.cloudservers.internal;
+
+import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
+
+import java.util.Date;
+import java.util.Properties;
+
+import org.jclouds.cloudservers.CloudServersClient;
+import org.jclouds.cloudservers.CloudServersContextBuilder;
+import org.jclouds.cloudservers.CloudServersPropertiesBuilder;
+import org.jclouds.cloudservers.config.CloudServersRestClientModule;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.http.RequiresHttp;
+import org.jclouds.openstack.config.OpenStackAuthenticationModule;
+import org.jclouds.openstack.filters.AddTimestampQuery;
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.jclouds.rest.ConfiguresRestClient;
+
+import com.google.common.base.Supplier;
+import com.google.inject.Module;
+
+/**
+ * Base class for writing CloudServers Rest Client Expect tests
+ *
+ * @author Adrian Cole
+ */
+public class BaseCloudServersRestClientExpectTest extends BaseRestClientExpectTest<CloudServersClient> {
+
+ public BaseCloudServersRestClientExpectTest() {
+ provider = "cloudservers";
+ }
+
+ @Override
+ protected Properties setupRestProperties() {
+ Properties overrides = new Properties();
+ overrides.setProperty(PROPERTY_REGIONS, "US");
+ overrides.setProperty(provider + ".endpoint", "https://auth");
+ overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName());
+ overrides.setProperty(provider + ".propertiesbuilder", CloudServersPropertiesBuilder.class.getName());
+ return overrides;
+ }
+
+ protected static final String CONSTANT_DATE = "2009-11-08T15:54:08.897Z";
+
+ /**
+ * override so that we can control the timestamp used in {@link AddTimestampQuery}
+ */
+ static class TestOpenStackAuthenticationModule extends OpenStackAuthenticationModule {
+ @Override
+ protected void configure() {
+ super.configure();
+ }
+
+ @Override
+ public Supplier<Date> provideCacheBusterDate() {
+ return new Supplier<Date>() {
+ public Date get() {
+ return new SimpleDateFormatDateService().iso8601DateParse(CONSTANT_DATE);
+ }
+ };
+ }
+
+ }
+
+ @Override
+ protected Module createModule() {
+ return new TestCloudServersRestClientModule();
+ }
+
+ @ConfiguresRestClient
+ @RequiresHttp
+ protected static class TestCloudServersRestClientModule extends CloudServersRestClientModule {
+ private TestCloudServersRestClientModule() {
+ super(new TestOpenStackAuthenticationModule());
+ }
+
+ }
+}
diff --git a/apis/cloudsigma/pom.xml b/apis/cloudsigma/pom.xml
index 6e491d9..c2cc9a2 100644
--- a/apis/cloudsigma/pom.xml
+++ b/apis/cloudsigma/pom.xml
@@ -35,12 +35,13 @@
<properties>
<test.cloudsigma.endpoint>https://api.cloudsigma.com</test.cloudsigma.endpoint>
- <test.cloudsigma.apiversion>1.0</test.cloudsigma.apiversion>
+ <test.cloudsigma.api-version>1.0</test.cloudsigma.api-version>
+ <test.cloudsigma.build-version></test.cloudsigma.build-version>
<test.cloudsigma.identity>FIXME</test.cloudsigma.identity>
<test.cloudsigma.credential>FIXME</test.cloudsigma.credential>
- <test.cloudsigma.image-id />
- <test.cloudsigma.image.login-user />
- <test.cloudsigma.image.authenticate-sudo />
+ <test.cloudsigma.image-id>f3c7c665-cd54-4a78-8fd2-7ec2f028cf29</test.cloudsigma.image-id>
+ <test.cloudsigma.image.login-user></test.cloudsigma.image.login-user>
+ <test.cloudsigma.image.authenticate-sudo></test.cloudsigma.image.authenticate-sudo>
</properties>
<dependencies>
@@ -94,7 +95,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudsigma.endpoint>${test.cloudsigma.endpoint}</test.cloudsigma.endpoint>
- <test.cloudsigma.apiversion>${test.cloudsigma.apiversion}</test.cloudsigma.apiversion>
+ <test.cloudsigma.api-version>${test.cloudsigma.api-version}</test.cloudsigma.api-version>
+ <test.cloudsigma.build-version>${test.cloudsigma.build-version}</test.cloudsigma.build-version>
<test.cloudsigma.identity>${test.cloudsigma.identity}</test.cloudsigma.identity>
<test.cloudsigma.credential>${test.cloudsigma.credential}</test.cloudsigma.credential>
<test.cloudsigma.image-id>${test.cloudsigma.image-id}</test.cloudsigma.image-id>
diff --git a/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java b/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java
index 9d0cd92..babe31d 100644
--- a/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java
+++ b/apis/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.cloudsigma;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -28,7 +27,6 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
-import org.jclouds.Constants;
import org.jclouds.cloudsigma.domain.ClaimType;
import org.jclouds.cloudsigma.domain.CreateDriveRequest;
import org.jclouds.cloudsigma.domain.DriveData;
@@ -46,6 +44,8 @@
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.predicates.DriveClaimed;
import org.jclouds.cloudsigma.util.Servers;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
+import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.LoginCredentials;
@@ -62,6 +62,7 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
@@ -73,56 +74,39 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", singleThreaded = true)
-public class CloudSigmaClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "CloudSigmaClientLiveTest")
+public class CloudSigmaClientLiveTest extends BaseVersionedServiceLiveTest {
+ public CloudSigmaClientLiveTest() {
+ provider = "cloudsigma";
+ }
+
protected long driveSize = 8 * 1024 * 1024 * 1024l;
protected int maxDriveImageTime = 300;
protected String vncPassword = "Il0veVNC";
- protected String bootDrive = "f3c7c665-cd54-4a78-8fd2-7ec2f028cf29";
protected CloudSigmaClient client;
protected RestContext<CloudSigmaClient, CloudSigmaAsyncClient> context;
protected Predicate<IPSocket> socketTester;
- protected String provider = "cloudsigma";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected Predicate<DriveInfo> driveNotClaimed;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
+ protected ComputeServiceContext computeContext;
@BeforeGroups(groups = "live")
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
- context = new ComputeServiceContextFactory().createContext(provider,
- ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
-
+ computeContext = new ComputeServiceContextFactory().createContext(provider,
+ ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides);
+ context = computeContext.getProviderSpecificContext();
+
client = context.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS);
+
+ if (Strings.emptyToNull(imageId) == null) {
+ imageId = computeContext.getComputeService().templateBuilder().build().getImage().getId();
+ }
}
@Test
@@ -459,7 +443,7 @@
protected void prepareDrive() {
client.destroyDrive(drive.getUuid());
- drive = client.cloneDrive(bootDrive, drive.getName(),
+ drive = client.cloneDrive(imageId, drive.getName(),
new CloneDriveOptions()
.size(driveSize)
.tags("cat:mouse", "monkey:banana")
diff --git a/apis/cloudstack/pom.xml b/apis/cloudstack/pom.xml
index fcc5ee1..090b0e9 100644
--- a/apis/cloudstack/pom.xml
+++ b/apis/cloudstack/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.cloudstack.endpoint>http://localhost:8080/client/api</test.cloudstack.endpoint>
- <test.cloudstack.apiversion>2.2.12</test.cloudstack.apiversion>
+ <test.cloudstack.api-version>2.2.12</test.cloudstack.api-version>
+ <test.cloudstack.build-version></test.cloudstack.build-version>
<test.cloudstack.identity>FIXME_apiKey</test.cloudstack.identity>
<test.cloudstack.credential>FIXME_secretKey</test.cloudstack.credential>
<test.cloudstack.domainAdminIdentity />
@@ -116,7 +117,8 @@
<threadCount>2</threadCount>
<systemPropertyVariables>
<test.cloudstack.endpoint>${test.cloudstack.endpoint}</test.cloudstack.endpoint>
- <test.cloudstack.apiversion>${test.cloudstack.apiversion}</test.cloudstack.apiversion>
+ <test.cloudstack.api-version>${test.cloudstack.api-version}</test.cloudstack.api-version>
+ <test.cloudstack.build-version>${test.cloudstack.build-version}</test.cloudstack.build-version>
<test.cloudstack.identity>${test.cloudstack.identity}</test.cloudstack.identity>
<test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential>
<test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id>
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContext.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContext.java
index 25dcb71..1eb716f 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContext.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContext.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack;
import org.jclouds.cloudstack.internal.CloudStackContextImpl;
@@ -15,8 +33,12 @@
@ImplementedBy(CloudStackContextImpl.class)
public interface CloudStackContext extends ComputeServiceContext {
- RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext();
-
- RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> getGlobalContext();
+ @SuppressWarnings("unchecked")
+ @Override
+ RestContext<CloudStackClient, CloudStackAsyncClient> getProviderSpecificContext();
+
+ RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext();
+
+ RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> getGlobalContext();
}
\ No newline at end of file
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalAsyncClient.java
index 6773098..b73d74a 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalAsyncClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalAsyncClient.java
@@ -21,6 +21,8 @@
import org.jclouds.cloudstack.features.GlobalAccountAsyncClient;
import org.jclouds.cloudstack.features.GlobalAlertAsyncClient;
import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient;
+import org.jclouds.cloudstack.features.GlobalConfigurationAsyncClient;
+import org.jclouds.cloudstack.features.GlobalConfigurationClient;
import org.jclouds.cloudstack.features.GlobalHostAsyncClient;
import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient;
@@ -90,4 +92,11 @@
*/
@Delegate
GlobalUsageAsyncClient getUsageClient();
+
+ /**
+ * Provides asynchronous access to Configuration
+ */
+ @Delegate
+ @Override
+ GlobalConfigurationAsyncClient getConfigurationClient();
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalClient.java
index a1f7367..b6dc916 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackGlobalClient.java
@@ -23,6 +23,7 @@
import org.jclouds.cloudstack.features.GlobalAccountClient;
import org.jclouds.cloudstack.features.GlobalAlertClient;
import org.jclouds.cloudstack.features.GlobalCapacityClient;
+import org.jclouds.cloudstack.features.GlobalConfigurationClient;
import org.jclouds.cloudstack.features.GlobalHostClient;
import org.jclouds.cloudstack.features.GlobalOfferingClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolClient;
@@ -94,4 +95,11 @@
*/
@Delegate
GlobalUsageClient getUsageClient();
+
+ /**
+ * Provides synchronous access to Configuration
+ */
+ @Delegate
+ @Override
+ GlobalConfigurationClient getConfigurationClient();
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java
index 0d0d77b..0238bc0 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java
@@ -19,6 +19,7 @@
package org.jclouds.cloudstack;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
+import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import java.util.Properties;
@@ -33,6 +34,7 @@
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
+ properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8080/client/api");
properties.setProperty(PROPERTY_API_VERSION, "2.2");
properties.setProperty("jclouds.ssh.max-retries", "7");
properties.setProperty("jclouds.ssh.retry-auth", "true");
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
index 8869ef3..fbf3193 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/config/CloudStackComputeServiceContextModule.java
@@ -29,6 +29,7 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient;
@@ -38,9 +39,13 @@
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata;
import org.jclouds.cloudstack.compute.functions.ZoneToLocation;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.compute.strategy.AdvancedNetworkOptionsConverter;
+import org.jclouds.cloudstack.compute.strategy.BasicNetworkOptionsConverter;
import org.jclouds.cloudstack.compute.strategy.CloudStackComputeServiceAdapter;
+import org.jclouds.cloudstack.compute.strategy.OptionsConverter;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template;
@@ -49,9 +54,11 @@
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork;
+import org.jclouds.cloudstack.functions.ZoneIdToZone;
import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.cloudstack.suppliers.GetCurrentUser;
import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser;
+import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
@@ -108,6 +115,10 @@
install(new FactoryModuleBuilder().build(StaticNATVirtualMachineInNetwork.Factory.class));
bind(new TypeLiteral<CacheLoader<Long, Set<IPForwardingRule>>>() {
}).to(GetIPForwardingRulesByVirtualMachine.class);
+ bind(new TypeLiteral<CacheLoader<Long, Zone>>() {
+ }).to(ZoneIdToZone.class);
+ bind(new TypeLiteral<Supplier<LoadingCache<Long, Zone>>>() {
+ }).to(ZoneIdToZoneSupplier.class);
}
@Provides
@@ -198,4 +209,11 @@
}
}
+ @Provides
+ @Singleton
+ Map<NetworkType, ? extends OptionsConverter> optionsConverters(){
+ return ImmutableMap.of(
+ NetworkType.ADVANCED, new AdvancedNetworkOptionsConverter(),
+ NetworkType.BASIC, new BasicNetworkOptionsConverter());
+ }
}
\ No newline at end of file
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java
index a98fcbd..6880782 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/functions/TemplateToOperatingSystem.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/AdvancedNetworkOptionsConverter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/AdvancedNetworkOptionsConverter.java
new file mode 100644
index 0000000..d8aa4d2
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/AdvancedNetworkOptionsConverter.java
@@ -0,0 +1,59 @@
+/**
+ * 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.cloudstack.compute.strategy;
+
+import com.google.common.collect.Iterables;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
+
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Predicates.and;
+import static com.google.common.collect.Iterables.filter;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.defaultNetworkInZone;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsStaticNAT;
+
+/**
+ * Convert template options into DeployVirtualMachineOptions, when the target zone has advanced networking.
+ *
+ * @author Richard Downer
+ */
+public class AdvancedNetworkOptionsConverter implements OptionsConverter {
+ @Override
+ public DeployVirtualMachineOptions apply(CloudStackTemplateOptions templateOptions, Map<Long, Network> networks, long zoneId, DeployVirtualMachineOptions options) {
+ // security groups not allowed.
+ // at least one network must be given to CloudStack,
+ // but jclouds will try to autodetect an appropriate network if none given.
+ checkArgument(templateOptions.getSecurityGroupIds().isEmpty(), "security groups cannot be specified for locations (zones) that use advanced networking");
+ if (templateOptions.getNetworkIds().size() > 0) {
+ options.networkIds(templateOptions.getNetworkIds());
+ } else {
+ checkArgument(!networks.isEmpty(), "please setup a network for zone: " + zoneId);
+ Network defaultNetworkInZone = Iterables.getFirst(filter(networks.values(), and(defaultNetworkInZone(zoneId), supportsStaticNAT())), null);
+ if(defaultNetworkInZone == null) {
+ throw new IllegalArgumentException("please choose a specific network in zone " + zoneId + ": " + networks);
+ } else {
+ options.networkId(defaultNetworkInZone.getId());
+ }
+ }
+ return options;
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/BasicNetworkOptionsConverter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/BasicNetworkOptionsConverter.java
new file mode 100644
index 0000000..072de8a
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/BasicNetworkOptionsConverter.java
@@ -0,0 +1,45 @@
+/**
+ * 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.cloudstack.compute.strategy;
+
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
+
+import java.util.Map;
+
+/**
+ * Convert template options into DeployVirtualMachineOptions, when the target zone has basic networking.
+ *
+ * @author Richard Downer
+ */
+public class BasicNetworkOptionsConverter implements OptionsConverter {
+ @Override
+ public DeployVirtualMachineOptions apply(CloudStackTemplateOptions templateOptions, Map<Long, Network> networks, long zoneId, DeployVirtualMachineOptions options) {
+ // both security groups and networks are optional, and CloudStack will
+ // use the zone/user's default network/security group if none given
+ if (templateOptions.getSecurityGroupIds().size() > 0) {
+ options.securityGroupIds(templateOptions.getSecurityGroupIds());
+ }
+ if (templateOptions.getNetworkIds().size() > 0) {
+ options.networkIds(templateOptions.getNetworkIds());
+ }
+ return options;
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
index c84b6c9..64f8325 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java
@@ -20,27 +20,33 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.and;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.cloudstack.options.DeployVirtualMachineOptions.Builder.displayName;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.defaultNetworkInZone;
import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsStaticNAT;
import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template;
@@ -88,6 +94,8 @@
private final CreatePortForwardingRulesForIP setupPortForwardingRulesForIP;
private final LoadingCache<Long, Set<IPForwardingRule>> vmToRules;
private final Map<String, Credentials> credentialStore;
+ private final Map<NetworkType, ? extends OptionsConverter> optionsConverters;
+ private final Supplier<LoadingCache<Long, Zone>> zoneIdToZone;
@Inject
public CloudStackComputeServiceAdapter(CloudStackClient client, Predicate<Long> jobComplete,
@@ -95,7 +103,8 @@
BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult,
StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork,
CreatePortForwardingRulesForIP setupPortForwardingRulesForIP, LoadingCache<Long, Set<IPForwardingRule>> vmToRules,
- Map<String, Credentials> credentialStore) {
+ Map<String, Credentials> credentialStore, Map<NetworkType, ? extends OptionsConverter> optionsConverters,
+ Supplier<LoadingCache<Long, Zone>> zoneIdToZone) {
this.client = checkNotNull(client, "client");
this.jobComplete = checkNotNull(jobComplete, "jobComplete");
this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier");
@@ -105,6 +114,8 @@
this.setupPortForwardingRulesForIP = checkNotNull(setupPortForwardingRulesForIP, "setupPortForwardingRulesForIP");
this.vmToRules = checkNotNull(vmToRules, "vmToRules");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
+ this.optionsConverters = optionsConverters;
+ this.zoneIdToZone = zoneIdToZone;
}
@Override
@@ -118,30 +129,19 @@
Map<Long, Network> networks = networkSupplier.get();
final long zoneId = Long.parseLong(template.getLocation().getId());
+ Zone zone = null;
+ try {
+ zone = zoneIdToZone.get().get(zoneId);
+ } catch (ExecutionException e) {
+ Throwables.propagate(e);
+ }
CloudStackTemplateOptions templateOptions = template.getOptions().as(CloudStackTemplateOptions.class);
- DeployVirtualMachineOptions options = displayName(name).name(name);
- if (templateOptions.getSecurityGroupIds().size() > 0) {
- options.securityGroupIds(templateOptions.getSecurityGroupIds());
- } else if (templateOptions.getNetworkIds().size() > 0) {
- options.networkIds(templateOptions.getNetworkIds());
- } else if (networks.size() > 0) {
- try {
- options.networkId(getOnlyElement(filter(networks.values(), and(new Predicate<Network>() {
-
- @Override
- public boolean apply(Network arg0) {
- return arg0.getZoneId() == zoneId && arg0.isDefault();
- }
-
- }, supportsStaticNAT()))).getId());
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("please choose a specific network in zone " + zoneId + ": " + networks);
- }
- } else {
- throw new IllegalArgumentException("please setup a network or security group for zone: " + zoneId);
- }
+ checkState(optionsConverters.containsKey(zone.getNetworkType()), "no options converter configured for network type %s",zone.getNetworkType());
+ DeployVirtualMachineOptions options = DeployVirtualMachineOptions.Builder.displayName(name).name(name);
+ OptionsConverter optionsConverter = optionsConverters.get(zone.getNetworkType());
+ options = optionsConverter.apply(templateOptions, networks, zoneId, options);
if (templateOptions.getIpOnDefaultNetwork() != null) {
options.ipOnDefaultNetwork(templateOptions.getIpOnDefaultNetwork());
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/OptionsConverter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/OptionsConverter.java
new file mode 100644
index 0000000..bbd0cf5
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/OptionsConverter.java
@@ -0,0 +1,54 @@
+/**
+ * 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.cloudstack.compute.strategy;
+
+import com.google.common.collect.Iterables;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
+
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Predicates.and;
+import static com.google.common.collect.Iterables.filter;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.defaultNetworkInZone;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsStaticNAT;
+
+/**
+ * Convert template options into DeployVirtualMachineOptions. Expressed as an interface, because in
+ * CloudStack different zone network types have different requirements when it comes to networks and
+ * security groups.
+ *
+ * @author Richard Downer
+ */
+public interface OptionsConverter {
+
+ /**
+ * Convert a CloudStackTemplateOptions and apply to a DeployVirtualMachineOptions instance.
+ *
+ * @param templateOptions the input set of options
+ * @param networks the networks available
+ * @param zoneId the zone of the new virtual machine
+ * @param options where the resulting set of options will be applied
+ * @return same as "options" parameter
+ */
+ DeployVirtualMachineOptions apply(CloudStackTemplateOptions templateOptions, Map<Long, Network> networks, long zoneId, DeployVirtualMachineOptions options);
+
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackParserModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackParserModule.java
index 0ac02f2..065662b 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackParserModule.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackParserModule.java
@@ -28,6 +28,7 @@
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.Account.State;
+import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.User;
@@ -46,20 +47,21 @@
/**
* Configures the cloudstack parsers.
- *
- * @author Adrian Cole
+ *
+ * @author Adrian Cole, Andrei Savu
*/
public class CloudStackParserModule extends AbstractModule {
- public static class PortForwardingRuleAdaptor implements JsonSerializer<PortForwardingRule>, JsonDeserializer<PortForwardingRule> {
+ @Singleton
+ public static class PortForwardingRuleAdapter implements JsonSerializer<PortForwardingRule>, JsonDeserializer<PortForwardingRule> {
public JsonElement serialize(PortForwardingRule src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
public PortForwardingRule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- return apply(context.<PortForwardingRuleInternal> deserialize(json, PortForwardingRuleInternal.class));
+ throws JsonParseException {
+ return apply(context.<PortForwardingRuleInternal>deserialize(json, PortForwardingRuleInternal.class));
}
public PortForwardingRule apply(PortForwardingRuleInternal in) {
@@ -85,10 +87,10 @@
private long IPAddressId;
@SerializedName("privateport")
private int privatePort;
- private String protocol;
+ private PortForwardingRule.Protocol protocol;
@SerializedName("publicport")
public int publicPort;
- private String state;
+ private PortForwardingRule.State state;
@SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName;
@SerializedName("virtualmachineid")
@@ -105,6 +107,52 @@
}
@Singleton
+ public static class FirewallRuleAdapter implements JsonSerializer<FirewallRule>, JsonDeserializer<FirewallRule> {
+
+ public JsonElement serialize(FirewallRule src, Type typeOfSrc, JsonSerializationContext context) {
+ return context.serialize(src);
+ }
+
+ public FirewallRule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+ return apply(context.<FirewallRuleInternal>deserialize(json, FirewallRuleInternal.class));
+ }
+
+ public FirewallRule apply(FirewallRuleInternal in) {
+ Set<String> cidrSet;
+ if (in.CIDRs != null) {
+ String[] elements = in.CIDRs.split(",");
+ cidrSet = Sets.newTreeSet(Arrays.asList(elements));
+ } else {
+ cidrSet = Collections.emptySet();
+ }
+ return FirewallRule.builder().id(in.id).CIDRs(cidrSet).startPort(in.startPort).endPort(in.endPort)
+ .icmpCode(in.icmpCode).icmpType(in.icmpType).ipAddress(in.ipAddress).ipAddressId(in.ipAddressId)
+ .protocol(in.protocol).state(in.state).build();
+ }
+
+ static final class FirewallRuleInternal {
+ private long id;
+ @SerializedName("cidrlist")
+ private String CIDRs;
+ @SerializedName("startport")
+ private int startPort;
+ @SerializedName("endport")
+ private int endPort;
+ @SerializedName("icmpcode")
+ private String icmpCode;
+ @SerializedName("icmptype")
+ private String icmpType;
+ @SerializedName("ipaddress")
+ private String ipAddress;
+ @SerializedName("ipaddressid")
+ private long ipAddressId;
+ private FirewallRule.Protocol protocol;
+ private FirewallRule.State state;
+ }
+ }
+
+ @Singleton
public static class LoadBalancerRuleAdapter implements JsonSerializer<LoadBalancerRule>, JsonDeserializer<LoadBalancerRule> {
public JsonElement serialize(LoadBalancerRule src, Type typeOfSrc, JsonSerializationContext context) {
@@ -112,8 +160,8 @@
}
public LoadBalancerRule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- return apply(context.<LoadBalancerRuleInternal> deserialize(json, LoadBalancerRuleInternal.class));
+ throws JsonParseException {
+ return apply(context.<LoadBalancerRuleInternal>deserialize(json, LoadBalancerRuleInternal.class));
}
public LoadBalancerRule apply(LoadBalancerRuleInternal in) {
@@ -157,22 +205,22 @@
}
public Account deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- return apply(context.<AccountInternal> deserialize(json, AccountInternal.class));
+ throws JsonParseException {
+ return apply(context.<AccountInternal>deserialize(json, AccountInternal.class));
}
public Account apply(AccountInternal in) {
return Account.builder().id(in.id).type(in.type).domain(in.domain).domainId(in.domainId)
- .IPsAvailable(nullIfUnlimited(in.IPsAvailable)).IPLimit(nullIfUnlimited(in.IPLimit)).IPs(in.IPs)
- .cleanupRequired(in.cleanupRequired).name(in.name).receivedBytes(in.receivedBytes)
- .sentBytes(in.sentBytes).snapshotsAvailable(nullIfUnlimited(in.snapshotsAvailable))
- .snapshotLimit(nullIfUnlimited(in.snapshotLimit)).snapshots(in.snapshots).state(in.state)
- .templatesAvailable(nullIfUnlimited(in.templatesAvailable))
- .templateLimit(nullIfUnlimited(in.templateLimit)).templates(in.templates)
- .VMsAvailable(nullIfUnlimited(in.VMsAvailable)).VMLimit(nullIfUnlimited(in.VMLimit))
- .VMsRunning(in.VMsRunning).VMsStopped(in.VMsStopped).VMs(in.VMs)
- .volumesAvailable(nullIfUnlimited(in.volumesAvailable)).volumeLimit(nullIfUnlimited(in.volumeLimit))
- .volumes(in.volumes).users(in.users).build();
+ .IPsAvailable(nullIfUnlimited(in.IPsAvailable)).IPLimit(nullIfUnlimited(in.IPLimit)).IPs(in.IPs)
+ .cleanupRequired(in.cleanupRequired).name(in.name).receivedBytes(in.receivedBytes)
+ .sentBytes(in.sentBytes).snapshotsAvailable(nullIfUnlimited(in.snapshotsAvailable))
+ .snapshotLimit(nullIfUnlimited(in.snapshotLimit)).snapshots(in.snapshots).state(in.state)
+ .templatesAvailable(nullIfUnlimited(in.templatesAvailable))
+ .templateLimit(nullIfUnlimited(in.templateLimit)).templates(in.templates)
+ .VMsAvailable(nullIfUnlimited(in.VMsAvailable)).VMLimit(nullIfUnlimited(in.VMLimit))
+ .VMsRunning(in.VMsRunning).VMsStopped(in.VMsStopped).VMs(in.VMs)
+ .volumesAvailable(nullIfUnlimited(in.volumesAvailable)).volumeLimit(nullIfUnlimited(in.volumeLimit))
+ .volumes(in.volumes).users(in.users).build();
}
static final class AccountInternal {
@@ -237,10 +285,11 @@
@Override
protected void configure() {
bind(new TypeLiteral<Map<Type, Object>>() {
- }).toInstance(ImmutableMap.<Type, Object> of(
+ }).toInstance(ImmutableMap.<Type, Object>of(
Account.class, new BreakGenericSetAdapter(),
LoadBalancerRule.class, new LoadBalancerRuleAdapter(),
- PortForwardingRule.class, new PortForwardingRuleAdaptor()
+ PortForwardingRule.class, new PortForwardingRuleAdapter(),
+ FirewallRule.class, new FirewallRuleAdapter()
));
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
index 5b2bc37..2c28734 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java
@@ -54,6 +54,8 @@
import org.jclouds.cloudstack.features.GlobalAlertClient;
import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient;
import org.jclouds.cloudstack.features.GlobalCapacityClient;
+import org.jclouds.cloudstack.features.GlobalConfigurationAsyncClient;
+import org.jclouds.cloudstack.features.GlobalConfigurationClient;
import org.jclouds.cloudstack.features.GlobalHostAsyncClient;
import org.jclouds.cloudstack.features.GlobalHostClient;
import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
@@ -138,6 +140,7 @@
.put(GuestOSClient.class, GuestOSAsyncClient.class)//
.put(HypervisorClient.class, HypervisorAsyncClient.class)//
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
+ .put(GlobalConfigurationClient.class, GlobalConfigurationAsyncClient.class)//
.put(AccountClient.class, AccountAsyncClient.class)//
.put(DomainAccountClient.class, DomainAccountAsyncClient.class)//
.put(DomainUserClient.class, DomainUserAsyncClient.class)//
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Cluster.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Cluster.java
new file mode 100644
index 0000000..edaf2ce
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Cluster.java
@@ -0,0 +1,248 @@
+/**
+ * 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.cloudstack.domain;
+
+import com.google.gson.annotations.SerializedName;
+
+import static com.google.common.base.CaseFormat.UPPER_CAMEL;
+import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
+
+/**
+ * Represents a CloudStack Cluster.
+ *
+ * @author Richard Downer
+ */
+public class Cluster implements Comparable<Cluster> {
+
+ public enum ManagedState {
+ MANAGED,
+ PREPARE_UNMANAGED,
+ UNMANAGED,
+ PREPARE_UNMANAGED_ERROR,
+ UNRECOGNIZED;
+
+ public static ManagedState fromValue(String value) {
+ try{
+ return valueOf(UPPER_CAMEL.to(UPPER_UNDERSCORE, value));
+ } catch (IllegalArgumentException e) {
+ return UNRECOGNIZED;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return UPPER_UNDERSCORE.to(UPPER_CAMEL, name());
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private long id;
+ private Host.AllocationState allocationState;
+ private Host.ClusterType clusterType;
+ private String hypervisor;
+ private ManagedState managedState;
+ private String name;
+ private long podId;
+ private String podName;
+ private long zoneId;
+ private String zoneName;
+
+ public Builder id(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder allocationState(Host.AllocationState allocationState) {
+ this.allocationState = allocationState;
+ return this;
+ }
+
+ public Builder clusterType(Host.ClusterType clusterType) {
+ this.clusterType = clusterType;
+ return this;
+ }
+
+ public Builder hypervisor(String hypervisor) {
+ this.hypervisor = hypervisor;
+ return this;
+ }
+
+ public Builder managedState(ManagedState managedState) {
+ this.managedState = managedState;
+ return this;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder podId(long podId) {
+ this.podId = podId;
+ return this;
+ }
+
+ public Builder podName(String podName) {
+ this.podName = podName;
+ return this;
+ }
+
+ public Builder zoneId(long zoneId) {
+ this.zoneId = zoneId;
+ return this;
+ }
+
+ public Builder zoneName(String zoneName) {
+ this.zoneName = zoneName;
+ return this;
+ }
+
+ public Cluster build() {
+ return new Cluster(id, allocationState, clusterType, hypervisor, managedState, name, podId, podName, zoneId, zoneName);
+ }
+ }
+
+ private long id;
+ @SerializedName("allocationstate") private Host.AllocationState allocationState;
+ @SerializedName("clustertype") private Host.ClusterType clusterType;
+ @SerializedName("hypervisortype") private String hypervisor;
+ @SerializedName("managedstate") private ManagedState managedState;
+ private String name;
+ @SerializedName("podid") private long podId;
+ @SerializedName("podname") private String podName;
+ @SerializedName("zoneid") private long zoneId;
+ @SerializedName("zonename") private String zoneName;
+
+ // Just for the serializer
+ Cluster() {}
+
+ public Cluster(long id, Host.AllocationState allocationState, Host.ClusterType clusterType, String hypervisor, ManagedState managedState, String name, long podId, String podName, long zoneId, String zoneName) {
+ this.id = id;
+ this.allocationState = allocationState;
+ this.clusterType = clusterType;
+ this.hypervisor = hypervisor;
+ this.managedState = managedState;
+ this.name = name;
+ this.podId = podId;
+ this.podName = podName;
+ this.zoneId = zoneId;
+ this.zoneName = zoneName;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public Host.AllocationState getAllocationState() {
+ return allocationState;
+ }
+
+ public Host.ClusterType getClusterType() {
+ return clusterType;
+ }
+
+ public String getHypervisor() {
+ return hypervisor;
+ }
+
+ public ManagedState getManagedState() {
+ return managedState;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public long getPodId() {
+ return podId;
+ }
+
+ public String getPodName() {
+ return podName;
+ }
+
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ public String getZoneName() {
+ return zoneName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Cluster cluster = (Cluster) o;
+
+ if (id != cluster.id) return false;
+ if (podId != cluster.podId) return false;
+ if (zoneId != cluster.zoneId) return false;
+ if (allocationState != cluster.allocationState) return false;
+ if (clusterType != cluster.clusterType) return false;
+ if (hypervisor != null ? !hypervisor.equals(cluster.hypervisor) : cluster.hypervisor != null) return false;
+ if (managedState != cluster.managedState) return false;
+ if (name != null ? !name.equals(cluster.name) : cluster.name != null) return false;
+ if (podName != null ? !podName.equals(cluster.podName) : cluster.podName != null) return false;
+ if (zoneName != null ? !zoneName.equals(cluster.zoneName) : cluster.zoneName != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (id ^ (id >>> 32));
+ result = 31 * result + (allocationState != null ? allocationState.hashCode() : 0);
+ result = 31 * result + (clusterType != null ? clusterType.hashCode() : 0);
+ result = 31 * result + (hypervisor != null ? hypervisor.hashCode() : 0);
+ result = 31 * result + (managedState != null ? managedState.hashCode() : 0);
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (int) (podId ^ (podId >>> 32));
+ result = 31 * result + (podName != null ? podName.hashCode() : 0);
+ result = 31 * result + (int) (zoneId ^ (zoneId >>> 32));
+ result = 31 * result + (zoneName != null ? zoneName.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Cluster{" +
+ "id=" + id +
+ ", allocationState=" + allocationState +
+ ", clusterType=" + clusterType +
+ ", hypervisor='" + hypervisor + '\'' +
+ ", managedState=" + managedState +
+ ", name='" + name + '\'' +
+ ", podId=" + podId +
+ ", podName='" + podName + '\'' +
+ ", zoneId=" + zoneId +
+ ", zoneName='" + zoneName + '\'' +
+ '}';
+ }
+
+ @Override
+ public int compareTo(Cluster other) {
+ return Long.valueOf(this.id).compareTo(other.id);
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ConfigurationEntry.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ConfigurationEntry.java
new file mode 100644
index 0000000..4756521
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ConfigurationEntry.java
@@ -0,0 +1,139 @@
+/**
+ * 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.cloudstack.domain;
+
+/**
+ * Representation of the API configuration entry response
+ *
+ * @author Andrei Savu
+ */
+public class ConfigurationEntry implements Comparable<ConfigurationEntry> {
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+
+ private String category;
+ private String description;
+ private String name;
+ private String value;
+
+ public Builder category(String category) {
+ this.category = category;
+ return this;
+ }
+
+ public Builder description(String description) {
+ this.description = description;
+ return this;
+ }
+
+ public Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder value(String value) {
+ this.value = value;
+ return this;
+ }
+
+ public ConfigurationEntry build() {
+ return new ConfigurationEntry(category, description, name, value);
+ }
+ }
+
+ // for deserialization
+ ConfigurationEntry() {
+ }
+
+ private String category;
+ private String description;
+ private String name;
+ private String value;
+
+ public ConfigurationEntry(String category, String description, String name, String value) {
+ this.category = category;
+ this.description = description;
+ this.name = name;
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(ConfigurationEntry arg0) {
+ return name.compareTo(arg0.getName());
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ConfigurationEntry that = (ConfigurationEntry) o;
+
+ if (category != null ? !category.equals(that.category) : that.category != null)
+ return false;
+ if (description != null ? !description.equals(that.description) : that.description != null)
+ return false;
+ if (name != null ? !name.equals(that.name) : that.name != null)
+ return false;
+ if (value != null ? !value.equals(that.value) : that.value != null)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = category != null ? category.hashCode() : 0;
+ result = 31 * result + (description != null ? description.hashCode() : 0);
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigurationEntry{" +
+ "category='" + category + '\'' +
+ ", description='" + description + '\'' +
+ ", name='" + name + '\'' +
+ ", value='" + value + '\'' +
+ '}';
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/FirewallRule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/FirewallRule.java
new file mode 100644
index 0000000..baf5fe6
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/FirewallRule.java
@@ -0,0 +1,288 @@
+/**
+ * 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.cloudstack.domain;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ImmutableSet;
+import com.google.gson.annotations.SerializedName;
+import org.omg.PortableInterceptor.ACTIVE;
+
+import java.util.Set;
+
+/**
+ * @author Andrei Savu
+ */
+public class FirewallRule implements Comparable<FirewallRule> {
+
+ public static enum Protocol {
+ TCP,
+ UDP,
+ ICMP,
+ UNKNOWN;
+
+ public static Protocol fromValue(String value) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch(IllegalArgumentException e) {
+ return UNKNOWN;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name().toUpperCase();
+ }
+ }
+
+ public static enum State {
+ STAGED, // Rule been created but has never got through network rule conflict detection.
+ // Rules in this state can not be sent to network elements.
+ ADD, // Add means the rule has been created and has gone through network rule conflict detection.
+ ACTIVE, // Rule has been sent to the network elements and reported to be active.
+ DELETEING, // Revoke means this rule has been revoked. If this rule has been sent to the
+ // network elements, the rule will be deleted from database.
+ UNKNOWN;
+
+ public static State fromValue(String value) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch(IllegalArgumentException e) {
+ return UNKNOWN;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private long id;
+ private Set<String> CIDRs;
+
+ private int startPort;
+ private int endPort;
+
+ private String icmpCode;
+ private String icmpType;
+
+ private String ipAddress;
+ private long ipAddressId;
+
+ private Protocol protocol;
+ private State state;
+
+ public Builder id(long id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder CIDRs(Set<String> CIDRs) {
+ this.CIDRs = ImmutableSet.copyOf(CIDRs);
+ return this;
+ }
+
+ public Builder startPort(int startPort) {
+ this.startPort = startPort;
+ return this;
+ }
+
+ public Builder endPort(int endPort) {
+ this.endPort = endPort;
+ return this;
+ }
+
+ public Builder icmpCode(String icmpCode) {
+ this.icmpCode = icmpCode;
+ return this;
+ }
+
+ public Builder icmpType(String icmpType) {
+ this.icmpType = icmpType;
+ return this;
+ }
+
+ public Builder ipAddress(String ipAddress) {
+ this.ipAddress = ipAddress;
+ return this;
+ }
+
+ public Builder ipAddressId(long ipAddressId) {
+ this.ipAddressId = ipAddressId;
+ return this;
+ }
+
+ public Builder protocol(Protocol protocol) {
+ this.protocol = protocol;
+ return this;
+ }
+
+ public Builder state(State state) {
+ this.state = state;
+ return this;
+ }
+
+ public FirewallRule build() {
+ return new FirewallRule(id, CIDRs, startPort, endPort, icmpCode,
+ icmpType, ipAddress, ipAddressId, protocol, state);
+ }
+ }
+
+ private long id;
+ @SerializedName("cidrlist")
+ private Set<String> CIDRs;
+ @SerializedName("startport")
+ private int startPort;
+ @SerializedName("endport")
+ private int endPort;
+ @SerializedName("icmpcode")
+ private String icmpCode;
+ @SerializedName("icmptype")
+ private String icmpType;
+ @SerializedName("ipaddress")
+ private String ipAddress;
+ @SerializedName("ipaddressid")
+ private long ipAddressId;
+ private Protocol protocol;
+ private State state;
+
+ public FirewallRule(long id, Set<String> CIDRs, int startPort, int endPort,
+ String icmpCode, String icmpType, String ipAddress, long ipAddressId,
+ Protocol protocol, State state) {
+ this.id = id;
+ this.CIDRs = ImmutableSet.copyOf(CIDRs);
+ this.startPort = startPort;
+ this.endPort = endPort;
+ this.icmpCode = icmpCode;
+ this.icmpType = icmpType;
+ this.ipAddress = ipAddress;
+ this.ipAddressId = ipAddressId;
+ this.protocol = protocol;
+ this.state = state;
+ }
+
+ @Override
+ public int compareTo(FirewallRule arg0) {
+ return new Long(id).compareTo(arg0.getId());
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public Set<String> getCIDRs() {
+ return CIDRs;
+ }
+
+ public int getStartPort() {
+ return startPort;
+ }
+
+ public int getEndPort() {
+ return endPort;
+ }
+
+ public String getIcmpCode() {
+ return icmpCode;
+ }
+
+ public String getIcmpType() {
+ return icmpType;
+ }
+
+ public String getIpAddress() {
+ return ipAddress;
+ }
+
+ public long getIpAddressId() {
+ return ipAddressId;
+ }
+
+ public Protocol getProtocol() {
+ return protocol;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ FirewallRule that = (FirewallRule) o;
+
+ if (endPort != that.endPort) return false;
+ if (id != that.id) return false;
+ if (startPort != that.startPort) return false;
+ if (CIDRs != null ? !CIDRs.equals(that.CIDRs) : that.CIDRs != null)
+ return false;
+ if (icmpCode != null ? !icmpCode.equals(that.icmpCode) : that.icmpCode != null)
+ return false;
+ if (icmpType != null ? !icmpType.equals(that.icmpType) : that.icmpType != null)
+ return false;
+ if (ipAddress != null ? !ipAddress.equals(that.ipAddress) : that.ipAddress != null)
+ return false;
+ if (ipAddressId != that.ipAddressId)
+ return false;
+ if (protocol != null ? !protocol.equals(that.protocol) : that.protocol != null)
+ return false;
+ if (state != null ? !state.equals(that.state) : that.state != null)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) (id ^ (id >>> 32));
+ result = 31 * result + (CIDRs != null ? CIDRs.hashCode() : 0);
+ result = 31 * result + startPort;
+ result = 31 * result + endPort;
+ result = 31 * result + (icmpCode != null ? icmpCode.hashCode() : 0);
+ result = 31 * result + (icmpType != null ? icmpType.hashCode() : 0);
+ result = 31 * result + (ipAddress != null ? ipAddress.hashCode() : 0);
+ result = 31 * result + (int) (ipAddressId ^ (ipAddressId >>> 32));
+ result = 31 * result + (protocol != null ? protocol.hashCode() : 0);
+ result = 31 * result + (state != null ? state.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "FirewallRule{" +
+ "id=" + id +
+ ", CIDRs='" + CIDRs + '\'' +
+ ", startPort=" + startPort +
+ ", endPort=" + endPort +
+ ", icmpCode='" + icmpCode + '\'' +
+ ", icmpType='" + icmpType + '\'' +
+ ", ipAddress='" + ipAddress + '\'' +
+ ", ipAddressId='" + ipAddressId + '\'' +
+ ", protocol='" + protocol + '\'' +
+ ", state='" + state + '\'' +
+ '}';
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/JobResult.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/JobResult.java
index 73f69ca..823114a 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/JobResult.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/JobResult.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.domain;
import com.google.gson.annotations.SerializedName;
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/PortForwardingRule.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/PortForwardingRule.java
index e0dada1..67c8ddb 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/PortForwardingRule.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/PortForwardingRule.java
@@ -20,15 +20,58 @@
import java.util.Set;
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
+import com.google.common.base.CaseFormat;
import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.SerializedName;
/**
- * @author Adrian Cole
+ * @author Adrian Cole, Andrei Savu
*/
public class PortForwardingRule implements Comparable<PortForwardingRule> {
+
+ public static enum Protocol {
+ TCP,
+ UDP,
+ ICMP,
+ UNKNOWN;
+
+ public static Protocol fromValue(String value) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return UNKNOWN;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
+ }
+
+ public static enum State {
+ STAGED, // Rule been created but has never got through network rule conflict detection.
+ // Rules in this state can not be sent to network elements.
+ ADD, // Add means the rule has been created and has gone through network rule conflict detection.
+ ACTIVE, // Rule has been sent to the network elements and reported to be active.
+ DELETEING, // Revoke means this rule has been revoked. If this rule has been sent to the
+ // network elements, the rule will be deleted from database.
+ UNKNOWN;
+
+ public static State fromValue(String value) {
+ try {
+ return valueOf(value.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return UNKNOWN;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name());
+ }
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -38,9 +81,9 @@
private String IPAddress;
private long IPAddressId;
private int privatePort;
- private String protocol;
+ private Protocol protocol;
public int publicPort;
- private String state;
+ private State state;
private String virtualMachineDisplayName;
public long virtualMachineId;
private String virtualMachineName;
@@ -68,7 +111,7 @@
return this;
}
- public Builder protocol(String protocol) {
+ public Builder protocol(Protocol protocol) {
this.protocol = protocol;
return this;
}
@@ -78,7 +121,7 @@
return this;
}
- public Builder state(String state) {
+ public Builder state(State state) {
this.state = state;
return this;
}
@@ -115,7 +158,7 @@
public PortForwardingRule build() {
return new PortForwardingRule(id, IPAddress, IPAddressId, privatePort, protocol, publicPort, state,
- virtualMachineDisplayName, virtualMachineId, virtualMachineName, CIDRs, privateEndPort, publicEndPort);
+ virtualMachineDisplayName, virtualMachineId, virtualMachineName, CIDRs, privateEndPort, publicEndPort);
}
}
@@ -126,10 +169,10 @@
private long IPAddressId;
@SerializedName("privateport")
private int privatePort;
- private String protocol;
+ private Protocol protocol;
@SerializedName("publicport")
public int publicPort;
- private String state;
+ private State state;
@SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName;
@SerializedName("virtualmachineid")
@@ -143,8 +186,8 @@
@SerializedName("publicendport")
private int publicEndPort;
- public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, String protocol,
- int publicPort, String state, String virtualMachineDisplayName, long virtualMachineId,
+ public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, Protocol protocol,
+ int publicPort, State state, String virtualMachineDisplayName, long virtualMachineId,
String virtualMachineName, Set<String> CIDRs, int privateEndPort, int publicEndPort) {
this.id = id;
this.IPAddress = iPAddress;
@@ -197,7 +240,7 @@
/**
* @return the protocol of the port forwarding rule
*/
- public String getProtocol() {
+ public Protocol getProtocol() {
return protocol;
}
@@ -211,7 +254,7 @@
/**
* @return the state of the rule
*/
- public String getState() {
+ public State getState() {
return state;
}
@@ -324,20 +367,20 @@
@Override
public String toString() {
return "PortForwardingRule{" +
- "id=" + id +
- ", IPAddress='" + IPAddress + '\'' +
- ", IPAddressId=" + IPAddressId +
- ", privatePort=" + privatePort +
- ", protocol='" + protocol + '\'' +
- ", publicPort=" + publicPort +
- ", state='" + state + '\'' +
- ", virtualMachineDisplayName='" + virtualMachineDisplayName + '\'' +
- ", virtualMachineId=" + virtualMachineId +
- ", virtualMachineName='" + virtualMachineName + '\'' +
- ", CIDRs=" + getCIDRs() +
- ", privateEndPort=" + privateEndPort +
- ", publicEndPort=" + publicEndPort +
- '}';
+ "id=" + id +
+ ", IPAddress='" + IPAddress + '\'' +
+ ", IPAddressId=" + IPAddressId +
+ ", privatePort=" + privatePort +
+ ", protocol='" + protocol + '\'' +
+ ", publicPort=" + publicPort +
+ ", state='" + state + '\'' +
+ ", virtualMachineDisplayName='" + virtualMachineDisplayName + '\'' +
+ ", virtualMachineId=" + virtualMachineId +
+ ", virtualMachineName='" + virtualMachineName + '\'' +
+ ", CIDRs=" + getCIDRs() +
+ ", privateEndPort=" + privateEndPort +
+ ", publicEndPort=" + publicEndPort +
+ '}';
}
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallAsyncClient.java
index 85b63b0..5c9ef48 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallAsyncClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallAsyncClient.java
@@ -26,15 +26,20 @@
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.filters.QuerySigner;
+import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
+import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.rest.annotations.ExceptionParser;
+import org.jclouds.rest.annotations.OnlyElement;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@@ -42,16 +47,55 @@
/**
* Provides asynchronous access to cloudstack via their REST API.
* <p/>
- *
+ *
+ * @author Adrian Cole
* @see FirewallClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
- * @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json")
public interface FirewallAsyncClient {
/**
+ * @see FirewallClient#listFirewallRules
+ */
+ @GET
+ @QueryParams(keys = "command", values = "listFirewallRules")
+ @SelectJson("firewallrule")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ ListenableFuture<Set<FirewallRule>> listFirewallRules(ListFirewallRulesOptions... options);
+
+ /**
+ * @see FirewallClient#getFirewallRule
+ */
+ @GET
+ @QueryParams(keys = "command", values = "listFirewallRules")
+ @SelectJson("firewallrule")
+ @OnlyElement
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
+ ListenableFuture<FirewallRule> getFirewallRule(@QueryParam("id") long id);
+
+ /**
+ * @see FirewallClient#createFirewallRuleForIpAndProtocol
+ */
+ @GET
+ @QueryParams(keys = "command", values = "createFirewallRule")
+ @Unwrap
+ @Consumes(MediaType.APPLICATION_JSON)
+ ListenableFuture<AsyncCreateResponse> createFirewallRuleForIpAndProtocol(@QueryParam("ipaddressid") long ipAddressId,
+ @QueryParam("protocol") FirewallRule.Protocol protocol, CreateFirewallRuleOptions... options);
+
+ /**
+ * @see FirewallClient#deleteFirewallRule
+ */
+ @GET
+ @QueryParams(keys = "command", values = "deleteFirewallRule")
+ @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
+ ListenableFuture<Void> deleteFirewallRule(@QueryParam("id") long id);
+
+ /**
* @see FirewallClient#listPortForwardingRules
*/
@GET
@@ -62,6 +106,17 @@
ListenableFuture<Set<PortForwardingRule>> listPortForwardingRules(ListPortForwardingRulesOptions... options);
/**
+ * @see FirewallClient#getPortForwardingRule
+ */
+ @GET
+ @QueryParams(keys = "command", values = "listPortForwardingRules")
+ @SelectJson("portforwardingrule")
+ @OnlyElement
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
+ ListenableFuture<PortForwardingRule> getPortForwardingRule(@QueryParam("id") long id);
+
+ /**
* @see FirewallClient#createPortForwardingRuleForVirtualMachine
*/
@GET
@@ -69,9 +124,9 @@
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<AsyncCreateResponse> createPortForwardingRuleForVirtualMachine(
- @QueryParam("virtualmachineid") long virtualMachineId, @QueryParam("ipaddressid") long IPAddressId,
- @QueryParam("protocol") String protocol, @QueryParam("privateport") int privatePort,
- @QueryParam("publicport") int publicPort);
+ @QueryParam("ipaddressid") long ipAddressId, @QueryParam("protocol") PortForwardingRule.Protocol protocol,
+ @QueryParam("publicport") int publicPort, @QueryParam("virtualmachineid") long virtualMachineId,
+ @QueryParam("privateport") int privatePort);
/**
* @see FirewallClient#deletePortForwardingRule
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallClient.java
index 3480016..ae02685 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/FirewallClient.java
@@ -22,7 +22,10 @@
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule;
+import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
+import org.jclouds.cloudstack.options.ListFirewallRulesOptions;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.concurrent.Timeout;
@@ -36,6 +39,49 @@
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface FirewallClient {
+
+ /**
+ * List the firewall rules
+ *
+ * @param options
+ * if present, how to constrain the list.
+ * @return
+ * set of firewall rules or empty set if no rules are found
+ */
+ Set<FirewallRule> listFirewallRules(ListFirewallRulesOptions... options);
+
+ /**
+ * Get a firewall rule by ID
+ *
+ * @param id
+ * the ID of the firewall rule
+ * @return
+ * firewall rule instance or null
+ */
+ FirewallRule getFirewallRule(long id);
+
+ /**
+ * Create new firewall rule for a specific IP address
+ *
+ * @param ipAddressId
+ * the IP address id of the port forwarding rule
+ * @param protocol
+ * the protocol for the firewall rule. Valid values are TCP/UDP/ICMP
+ * @param options
+ * optional arguments for firewall rule creation
+ * @return
+ */
+ AsyncCreateResponse createFirewallRuleForIpAndProtocol(long ipAddressId,
+ FirewallRule.Protocol protocol, CreateFirewallRuleOptions... options);
+
+ /**
+ * Deletes a firewall rule
+ *
+ * @param id
+ * the ID of the firewall rule
+ */
+ Void deleteFirewallRule(long id);
+
/**
* List the port forwarding rules
*
@@ -47,23 +93,32 @@
Set<PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesOptions... options);
/**
+ * Get a port forwarding rule by ID
+ *
+ * @param id
+ * port forwarding rule ID
+ * @return
+ * rule instance or null
+ */
+ PortForwardingRule getPortForwardingRule(long id);
+
+ /**
* Creates an port forwarding rule
*
- * @param virtualMachineId
- * the ID of the virtual machine for the port forwarding rule
- * @param IPAddressId
- * the public IP address id of the forwarding rule, already
- * associated via associatePort
+ *
+ * @param ipAddressId
* @param protocol
* the protocol for the rule. Valid values are TCP or UDP.
- * @param privatePort
- * the private port of the port forwarding rule
* @param publicPort
* the public port of the port forwarding rule
+ * @param virtualMachineId
+ * the ID of the virtual machine for the port forwarding rule
+ * @param privatePort
+ * the private port of the port forwarding rule
* @return response used to track creation
*/
- AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long virtualMachineId, long IPAddressId,
- String protocol, int privatePort, int publicPort);
+ AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long ipAddressId,
+ PortForwardingRule.Protocol protocol, int publicPort, long virtualMachineId, int privatePort);
/**
* Deletes an port forwarding rule
@@ -71,5 +126,5 @@
* @param id
* the id of the forwarding rule
*/
- void deletePortForwardingRule(long id);
+ Void deletePortForwardingRule(long id);
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationAsyncClient.java
new file mode 100644
index 0000000..21212e3
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationAsyncClient.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cloudstack.features;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.jclouds.cloudstack.domain.ConfigurationEntry;
+import org.jclouds.cloudstack.filters.QuerySigner;
+import org.jclouds.cloudstack.options.ListConfigurationEntriesOptions;
+import org.jclouds.rest.annotations.ExceptionParser;
+import org.jclouds.rest.annotations.OnlyElement;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import java.util.Set;
+
+/**
+ * Provides asynchronous access to CloudStack Configuration features available to Global
+ * Admin users.
+ *
+ * @author Andrei Savu
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
+ * />
+ */
+@RequestFilters(QuerySigner.class)
+@QueryParams(keys = "response", values = "json")
+public interface GlobalConfigurationAsyncClient extends ConfigurationAsyncClient {
+
+ /**
+ * @see GlobalConfigurationClient#listConfigurationEntries
+ */
+ @GET
+ @QueryParams(keys = "command", values = "listConfigurations")
+ @SelectJson("configuration")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ ListenableFuture<Set<ConfigurationEntry>> listConfigurationEntries(ListConfigurationEntriesOptions... options);
+
+ /**
+ * @see GlobalConfigurationClient#updateConfigurationEntry
+ */
+ @GET
+ @QueryParams(keys = "command", values = "updateConfiguration")
+ @SelectJson("configuration")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
+ ListenableFuture<ConfigurationEntry> updateConfigurationEntry(
+ @QueryParam("name") String name, @QueryParam("value") String value);
+}
\ No newline at end of file
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationClient.java
new file mode 100644
index 0000000..1b03c43
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalConfigurationClient.java
@@ -0,0 +1,61 @@
+/**
+ * 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.cloudstack.features;
+
+import org.jclouds.cloudstack.domain.ConfigurationEntry;
+import org.jclouds.cloudstack.options.ListConfigurationEntriesOptions;
+import org.jclouds.concurrent.Timeout;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Provides synchronous access to CloudStack Configuration features available to Global
+ * Admin users.
+ *
+ * @author Andrei Savu
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_Global_Admin.html"
+ * />
+ */
+@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
+public interface GlobalConfigurationClient extends ConfigurationClient {
+
+ /**
+ * List all configuration entries
+ *
+ * @param options
+ * result set filtering options
+ * @return
+ * a set of entries or empty
+ */
+ Set<ConfigurationEntry> listConfigurationEntries(ListConfigurationEntriesOptions... options);
+
+ /**
+ * Update a configuration entry
+ *
+ * @param name
+ * the name of the configuration
+ * @param value
+ * the value of the configuration
+ * @return
+ * the updated configuration value
+ */
+ ConfigurationEntry updateConfigurationEntry(String name, String value);
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java
index 2a91b08..a6fc4d0 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java
@@ -19,8 +19,10 @@
package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture;
+import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host;
import org.jclouds.cloudstack.filters.QuerySigner;
+import org.jclouds.cloudstack.options.ListClustersOptions;
import org.jclouds.cloudstack.options.ListHostsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
@@ -54,4 +56,14 @@
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Host>> listHosts(ListHostsOptions... options);
+
+ /**
+ * @see GlobalHostClient#listClusters
+ */
+ @GET
+ @QueryParams(keys = "command", values = "listClusters")
+ @SelectJson("cluster")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ ListenableFuture<Set<Cluster>> listClusters(ListClustersOptions... options);
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java
index 6103fe4..414ce8b 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java
@@ -18,7 +18,9 @@
*/
package org.jclouds.cloudstack.features;
+import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host;
+import org.jclouds.cloudstack.options.ListClustersOptions;
import org.jclouds.cloudstack.options.ListHostsOptions;
import org.jclouds.concurrent.Timeout;
@@ -46,4 +48,11 @@
*/
Set<Host> listHosts(ListHostsOptions... options);
+ /**
+ * Lists clusters
+ *
+ * @param options if present, how to constrain the list
+ * @return clusters matching query, or empty set if no clusters match
+ */
+ Set<Cluster> listClusters(ListClustersOptions... options);
}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java
index db05a7e..da9b821 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java
@@ -29,7 +29,9 @@
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.filters.QuerySigner;
+import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
+import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.functions.JoinOnComma;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
@@ -76,7 +78,7 @@
ListenableFuture<LoadBalancerRule> getLoadBalancerRule(@QueryParam("id") long id);
/**
- * @see LoadBalancerClient#createLoadBalancerRuleForPublicIp
+ * @see LoadBalancerClient#createLoadBalancerRuleForPublicIP
*/
@GET
@QueryParams(keys = "command", values = "createLoadBalancerRule")
@@ -84,7 +86,19 @@
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId,
@QueryParam("algorithm") Algorithm algorithm, @QueryParam("name") String name,
- @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort);
+ @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort,
+ CreateLoadBalancerRuleOptions... options);
+
+ /**
+ * @see LoadBalancerClient#updateLoadBalancerRule
+ */
+ @GET
+ @QueryParams(keys = "command", values ="updateLoadBalancerRule")
+ @SelectJson("loadbalancerrule")
+ @OnlyElement
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
+ ListenableFuture<LoadBalancerRule> updateLoadBalancerRule(@QueryParam("id") long id, UpdateLoadBalancerRuleOptions... options);
/**
* @see LoadBalancerClient#deleteLoadBalancerRule
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java
index 8e6da5e..ab20d2e 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java
@@ -24,7 +24,9 @@
import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine;
+import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
+import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.concurrent.Timeout;
/**
@@ -72,10 +74,22 @@
* @param publicPort
* public ip address id from where the network traffic will be load
* balanced from
+ * @param options optional call arguments
* @return newly created rule
*/
Long createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name,
- int privatePort, int publicPort);
+ int privatePort, int publicPort, CreateLoadBalancerRuleOptions... options);
+
+ /**
+ * Update a load balancer rule.
+ *
+ * @param id
+ * rule id
+ * @param options
+ * optional arguments
+ * @return updated rule
+ */
+ LoadBalancerRule updateLoadBalancerRule(long id, UpdateLoadBalancerRuleOptions... options);
/**
*
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ZoneIdToZone.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ZoneIdToZone.java
new file mode 100644
index 0000000..8ee174f
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ZoneIdToZone.java
@@ -0,0 +1,50 @@
+/**
+ * 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.cloudstack.functions;
+
+import com.google.common.cache.CacheLoader;
+import com.google.inject.Inject;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.domain.Zone;
+import org.jclouds.cloudstack.features.ZoneClient;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Defines a cache that allows a zone to be looked up by its ID.
+ *
+ * @author Richard Downer
+ */
+public class ZoneIdToZone extends CacheLoader<Long, Zone> {
+
+ private final ZoneClient zoneClient;
+
+ @Inject
+ public ZoneIdToZone(CloudStackClient client) {
+ checkNotNull(client, "client");
+ this.zoneClient = client.getZoneClient();
+ }
+
+ @Override
+ public Zone load(Long zoneId) throws Exception {
+ checkNotNull(zoneId, "zoneId");
+ return zoneClient.getZone(zoneId);
+ }
+
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java
index d033e5e..34b8e70 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/internal/CloudStackContextImpl.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.internal;
import java.util.Map;
@@ -24,19 +42,27 @@
@Singleton
public class CloudStackContextImpl extends ComputeServiceContextImpl<CloudStackClient, CloudStackAsyncClient> implements
CloudStackContext {
+ private final RestContext<CloudStackClient,CloudStackAsyncClient> providerSpecificContext;
private final RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext;
private final RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext;
@Inject
public CloudStackContextImpl(ComputeService computeService, Map<String, Credentials> credentialStore, Utils utils,
- @SuppressWarnings("rawtypes") RestContext providerSpecificContext,
+ RestContext<CloudStackClient,CloudStackAsyncClient> providerSpecificContext,
RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext,
RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext) {
super(computeService, credentialStore, utils, providerSpecificContext);
+ this.providerSpecificContext=providerSpecificContext;
this.domainContext = domainContext;
this.globalContext = globalContext;
}
-
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public RestContext<CloudStackClient,CloudStackAsyncClient> getProviderSpecificContext() {
+ return providerSpecificContext;
+ }
+
@Override
public RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext() {
return domainContext;
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateFirewallRuleOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateFirewallRuleOptions.java
new file mode 100644
index 0000000..00b37bd
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateFirewallRuleOptions.java
@@ -0,0 +1,126 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+import java.util.Set;
+
+/**
+ * Options used to control how a firewall rule is created
+ *
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/createFirewallRule.html"
+ * />
+ * @author Andrei Savu
+ */
+public class CreateFirewallRuleOptions extends BaseHttpRequestOptions {
+
+ public static final CreateFirewallRuleOptions NONE = new CreateFirewallRuleOptions();
+
+ /**
+ * @param CIDRs
+ * the list of CIDRs to forward traffic from
+ */
+ public CreateFirewallRuleOptions CIDRs(Set<String> CIDRs) {
+ this.queryParameters.replaceValues("cidrlist", ImmutableSet.of(Joiner.on(",").join(CIDRs)));
+ return this;
+ }
+
+ /**
+ * @param startPort
+ * the starting port of firewall rule
+ */
+ public CreateFirewallRuleOptions startPort(int startPort) {
+ this.queryParameters.replaceValues("startport", ImmutableSet.of(startPort + ""));
+ return this;
+ }
+
+ /**
+ * @param endPort
+ * the ending port of firewall rule
+ */
+ public CreateFirewallRuleOptions endPort(int endPort) {
+ this.queryParameters.replaceValues("endport", ImmutableSet.of(endPort + ""));
+ return this;
+ }
+
+ /**
+ * @param icmpCode
+ * error code for this icmp message
+ */
+ public CreateFirewallRuleOptions icmpCode(String icmpCode) {
+ this.queryParameters.replaceValues("icmpcode", ImmutableSet.of(icmpCode));
+ return this;
+ }
+
+ /**
+ * @param icmpType
+ * type of the icmp message being sent
+ */
+ public CreateFirewallRuleOptions icmpType(String icmpType) {
+ this.queryParameters.replaceValues("icmptype", ImmutableSet.of(icmpType));
+ return this;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see CreateFirewallRuleOptions#CIDRs
+ */
+ public static CreateFirewallRuleOptions CIDRs(Set<String> CIDRs) {
+ CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
+ return options.CIDRs(CIDRs);
+ }
+
+ /**
+ * @see CreateFirewallRuleOptions#startPort
+ */
+ public static CreateFirewallRuleOptions startPort(int startPort) {
+ CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
+ return options.startPort(startPort);
+ }
+
+ /**
+ * @see CreateFirewallRuleOptions#endPort
+ */
+ public static CreateFirewallRuleOptions endPort(int endPort) {
+ CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
+ return options.endPort(endPort);
+ }
+
+ /**
+ * @see CreateFirewallRuleOptions#icmpCode
+ */
+ public static CreateFirewallRuleOptions icmpCode(String icmpCode) {
+ CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
+ return options.icmpCode(icmpCode);
+ }
+
+ /**
+ * @see CreateFirewallRuleOptions#icmpType
+ */
+ public static CreateFirewallRuleOptions icmpType(String icmpType) {
+ CreateFirewallRuleOptions options = new CreateFirewallRuleOptions();
+ return options.icmpType(icmpType);
+ }
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateLoadBalancerRuleOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateLoadBalancerRuleOptions.java
new file mode 100644
index 0000000..c1a0049
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateLoadBalancerRuleOptions.java
@@ -0,0 +1,138 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
+/**
+ * Options used to control what load balancer rules are returned
+ *
+ * @author Adrian Cole, Andrei Savu
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/user/createLoadBalancerRule.html"
+ * />
+ */
+public class CreateLoadBalancerRuleOptions extends AccountInDomainOptions {
+
+ public static final CreateLoadBalancerRuleOptions NONE = new CreateLoadBalancerRuleOptions();
+
+ /**
+ * @param allowedSourceCIRDs the cidr list to forward traffic from
+ */
+ public CreateLoadBalancerRuleOptions allowedSourceCIDRs(Set<String> allowedSourceCIRDs) {
+ this.queryParameters.replaceValues("cidrlist",
+ ImmutableSet.of(Joiner.on(",").join(allowedSourceCIRDs)));
+ return this;
+ }
+
+ /**
+ * @param description the description of the load balancer rule
+ */
+ public CreateLoadBalancerRuleOptions description(String description) {
+ this.queryParameters.replaceValues("description", ImmutableSet.of(description));
+ return this;
+ }
+
+ /**
+ * @param openFirewall if true, firewall rule for source/end pubic port is automatically
+ * created; if false - firewall rule has to be created explicitly. Has value true by default
+ */
+ public CreateLoadBalancerRuleOptions openFirewall(boolean openFirewall) {
+ this.queryParameters.replaceValues("openfirewall", ImmutableSet.of(openFirewall + ""));
+ return this;
+ }
+
+ /**
+ * @param zoneId the availability zone ID
+ */
+ public CreateLoadBalancerRuleOptions zoneId(long zoneId) {
+ this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId + ""));
+ return this;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#allowedSourceCIDRs
+ */
+ public static CreateLoadBalancerRuleOptions allowedSourceCIDRs(Set<String> allowedSourceCIDRs) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.allowedSourceCIDRs(allowedSourceCIDRs);
+ }
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#description
+ */
+ public static CreateLoadBalancerRuleOptions description(String description) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.description(description);
+ }
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#openFirewall
+ */
+ public static CreateLoadBalancerRuleOptions openFirewall(boolean openFirewall) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.openFirewall(openFirewall);
+ }
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#zoneId
+ */
+ public static CreateLoadBalancerRuleOptions zoneId(long zoneId) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.zoneId(zoneId);
+ }
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#accountInDomain
+ */
+ public static CreateLoadBalancerRuleOptions accountInDomain(String account, long domain) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.accountInDomain(account, domain);
+ }
+
+ /**
+ * @see CreateLoadBalancerRuleOptions#domainId
+ */
+ public static CreateLoadBalancerRuleOptions domainId(long id) {
+ CreateLoadBalancerRuleOptions options = new CreateLoadBalancerRuleOptions();
+ return options.domainId(id);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CreateLoadBalancerRuleOptions accountInDomain(String account, long domain) {
+ return CreateLoadBalancerRuleOptions.class.cast(super.accountInDomain(account, domain));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public CreateLoadBalancerRuleOptions domainId(long domainId) {
+ return CreateLoadBalancerRuleOptions.class.cast(super.domainId(domainId));
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateSnapshotOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateSnapshotOptions.java
index 40ddc09..7a1ce24 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateSnapshotOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateSnapshotOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/DeleteISOOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/DeleteISOOptions.java
index d0752d8..21061bb 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/DeleteISOOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/DeleteISOOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ExtractISOOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ExtractISOOptions.java
index 9d70c6d..a0b8de2 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ExtractISOOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ExtractISOOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListClustersOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListClustersOptions.java
new file mode 100644
index 0000000..667b403
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListClustersOptions.java
@@ -0,0 +1,122 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.cloudstack.domain.Cluster;
+import org.jclouds.cloudstack.domain.Host;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Options used to control what cluster information is returned
+ *
+ * @author Richard Downer
+ * @see <a
+ * href="http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listClusters.html"
+ * />
+ */
+public class ListClustersOptions extends BaseHttpRequestOptions {
+
+ public static final ListHostsOptions NONE = new ListHostsOptions();
+
+ public ListClustersOptions allocationState(Host.AllocationState allocationState) {
+ this.queryParameters.replaceValues("allocationstate", ImmutableSet.of(allocationState.toString()));
+ return this;
+ }
+
+ public ListClustersOptions clusterType(Host.ClusterType clusterType) {
+ this.queryParameters.replaceValues("clustertype", ImmutableSet.of(clusterType.toString()));
+ return this;
+ }
+
+ public ListClustersOptions hypervisor(String hypervisor) {
+ this.queryParameters.replaceValues("hypervisor", ImmutableSet.of(hypervisor));
+ return this;
+ }
+
+ public ListClustersOptions id(long id) {
+ this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
+ return this;
+ }
+
+ public ListClustersOptions keyword(String keyword) {
+ this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
+ return this;
+ }
+
+ public ListClustersOptions managedState(Cluster.ManagedState managedState) {
+ this.queryParameters.replaceValues("managedstate", ImmutableSet.of(managedState.toString()));
+ return this;
+ }
+
+ public ListClustersOptions name(String name) {
+ this.queryParameters.replaceValues("name", ImmutableSet.of(name));
+ return this;
+ }
+
+ public ListClustersOptions podId(long podId) {
+ this.queryParameters.replaceValues("podid", ImmutableSet.of(podId + ""));
+ return this;
+ }
+
+ public ListClustersOptions zoneId(long zoneId) {
+ this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId + ""));
+ return this;
+ }
+
+ public static class Builder {
+
+ public static ListClustersOptions allocationState(Host.AllocationState allocationState) {
+ return new ListClustersOptions().allocationState(allocationState);
+ }
+
+ public static ListClustersOptions clusterType(Host.ClusterType clusterType) {
+ return new ListClustersOptions().clusterType(clusterType);
+ }
+
+ public static ListClustersOptions hypervisor(String hypervisor) {
+ return new ListClustersOptions().hypervisor(hypervisor);
+ }
+
+ public static ListClustersOptions id(long id) {
+ return new ListClustersOptions().id(id);
+ }
+
+ public static ListClustersOptions keyword(String keyword) {
+ return new ListClustersOptions().keyword(keyword);
+ }
+
+ public static ListClustersOptions managedState(Cluster.ManagedState managedState) {
+ return new ListClustersOptions().managedState(managedState);
+ }
+
+ public static ListClustersOptions name(String name) {
+ return new ListClustersOptions().name(name);
+ }
+
+ public static ListClustersOptions podId(long podId) {
+ return new ListClustersOptions().podId(podId);
+ }
+
+ public static ListClustersOptions zoneId(long zoneId) {
+ return new ListClustersOptions().zoneId(zoneId);
+ }
+
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListConfigurationEntriesOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListConfigurationEntriesOptions.java
new file mode 100644
index 0000000..1f585ae
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListConfigurationEntriesOptions.java
@@ -0,0 +1,115 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Options used to control what configuration entries are returned
+ *
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listConfigurations.html"
+ * />
+ * @author Andrei Savu
+ */
+public class ListConfigurationEntriesOptions extends BaseHttpRequestOptions {
+
+ public static final ListConfigurationEntriesOptions NONE = new ListConfigurationEntriesOptions();
+
+ /**
+ * @param category
+ * list by category name
+ */
+ public ListConfigurationEntriesOptions category(String category) {
+ this.queryParameters.replaceValues("category", ImmutableSet.of(category));
+ return this;
+ }
+
+ /**
+ * @param keyword
+ * list by keyword
+ */
+ public ListConfigurationEntriesOptions keyword(String keyword) {
+ this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
+ return this;
+ }
+
+ /**
+ * @param name
+ * list by entry name
+ */
+ public ListConfigurationEntriesOptions name(String name) {
+ this.queryParameters.replaceValues("name", ImmutableSet.of(name));
+ return this;
+ }
+
+ public ListConfigurationEntriesOptions page(long page) {
+ this.queryParameters.replaceValues("page", ImmutableSet.of(page + ""));
+ return this;
+ }
+
+ public ListConfigurationEntriesOptions pageSize(long pageSize) {
+ this.queryParameters.replaceValues("pagesize", ImmutableSet.of(pageSize + ""));
+ return this;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see ListConfigurationEntriesOptions#category
+ */
+ public static ListConfigurationEntriesOptions category(String category) {
+ ListConfigurationEntriesOptions options = new ListConfigurationEntriesOptions();
+ return options.category(category);
+ }
+
+ /**
+ * @see ListConfigurationEntriesOptions#keyword
+ */
+ public static ListConfigurationEntriesOptions keyword(String keyword) {
+ ListConfigurationEntriesOptions options = new ListConfigurationEntriesOptions();
+ return options.keyword(keyword);
+ }
+
+ /**
+ * @see ListConfigurationEntriesOptions#name
+ */
+ public static ListConfigurationEntriesOptions name(String name) {
+ ListConfigurationEntriesOptions options = new ListConfigurationEntriesOptions();
+ return options.name(name);
+ }
+
+ /**
+ * @see ListConfigurationEntriesOptions#page
+ */
+ public static ListConfigurationEntriesOptions page(long page) {
+ ListConfigurationEntriesOptions options = new ListConfigurationEntriesOptions();
+ return options.page(page);
+ }
+
+ /**
+ * @see ListConfigurationEntriesOptions#pageSize
+ */
+ public static ListConfigurationEntriesOptions pageSize(long pageSize) {
+ ListConfigurationEntriesOptions options = new ListConfigurationEntriesOptions();
+ return options.pageSize(pageSize);
+ }
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListFirewallRulesOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListFirewallRulesOptions.java
new file mode 100644
index 0000000..4b683e9
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListFirewallRulesOptions.java
@@ -0,0 +1,147 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Options used to control what firewall rules are returned
+ *
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listFirewallRules.html"
+ * />
+ * @author Andrei Savu
+ */
+public class ListFirewallRulesOptions extends AccountInDomainOptions {
+
+ public static final ListFirewallRulesOptions NONE = new ListFirewallRulesOptions();
+
+ /**
+ * @param id
+ * firewall rule ID
+ */
+ public ListFirewallRulesOptions id(long id) {
+ this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
+ return this;
+ }
+
+ /**
+ * @param ipAddressId
+ * the id of IP address of the firwall services
+ */
+ public ListFirewallRulesOptions ipAddressId(long ipAddressId) {
+ this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(ipAddressId + ""));
+ return this;
+ }
+
+ /**
+ * @param keyword
+ * list by keyword
+ */
+ public ListFirewallRulesOptions keyword(String keyword) {
+ this.queryParameters.replaceValues("keyword", ImmutableSet.of(keyword));
+ return this;
+ }
+
+ public ListFirewallRulesOptions page(long page) {
+ this.queryParameters.replaceValues("page", ImmutableSet.of(page + ""));
+ return this;
+ }
+
+ public ListFirewallRulesOptions pageSize(long pageSize) {
+ this.queryParameters.replaceValues("pagesize", ImmutableSet.of(pageSize + ""));
+ return this;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see ListFirewallRulesOptions#id
+ */
+ public static ListFirewallRulesOptions id(long id) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.id(id);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#ipAddressId
+ */
+ public static ListFirewallRulesOptions ipAddressId(long ipAddressId) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.ipAddressId(ipAddressId);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#keyword
+ */
+ public static ListFirewallRulesOptions keyword(String keyword) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.keyword(keyword);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#page
+ */
+ public static ListFirewallRulesOptions page(long page) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.page(page);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#pageSize
+ */
+ public static ListFirewallRulesOptions pageSize(long pageSize) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.pageSize(pageSize);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#accountInDomain
+ */
+ public static ListFirewallRulesOptions accountInDomain(String account, long domain) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.accountInDomain(account, domain);
+ }
+
+ /**
+ * @see ListFirewallRulesOptions#domainId
+ */
+ public static ListFirewallRulesOptions domainId(long id) {
+ ListFirewallRulesOptions options = new ListFirewallRulesOptions();
+ return options.domainId(id);
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ListFirewallRulesOptions accountInDomain(String account, long domain) {
+ return ListFirewallRulesOptions.class.cast(super.accountInDomain(account, domain));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ListFirewallRulesOptions domainId(long domainId) {
+ return ListFirewallRulesOptions.class.cast(super.domainId(domainId));
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListISOsOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListISOsOptions.java
index f3fdef4..cabb8aa 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListISOsOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListISOsOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptions.java
index 72f0619..5ca3882 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptions.java
@@ -66,7 +66,30 @@
public ListLoadBalancerRulesOptions virtualMachineId(long virtualMachineId) {
this.queryParameters.replaceValues("virtualmachineid", ImmutableSet.of(virtualMachineId + ""));
return this;
+ }
+ /**
+ * @param zoneId the availability zone ID
+ */
+ public ListLoadBalancerRulesOptions zoneId(long zoneId) {
+ this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId + ""));
+ return this;
+ }
+
+ /**
+ * @param page the number of the page
+ */
+ public ListLoadBalancerRulesOptions page(long page) {
+ this.queryParameters.replaceValues("page", ImmutableSet.of(page + ""));
+ return this;
+ }
+
+ /**
+ * @param pageSize
+ */
+ public ListLoadBalancerRulesOptions pageSize(long pageSize) {
+ this.queryParameters.replaceValues("pagesize", ImmutableSet.of(pageSize + ""));
+ return this;
}
public static class Builder {
@@ -118,6 +141,30 @@
ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions();
return options.virtualMachineId(virtualMachineId);
}
+
+ /**
+ * @see ListLoadBalancerRulesOptions#zoneId
+ */
+ public static ListLoadBalancerRulesOptions zoneId(long zoneId) {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions();
+ return options.zoneId(zoneId);
+ }
+
+ /**
+ * @see ListLoadBalancerRulesOptions#page
+ */
+ public static ListLoadBalancerRulesOptions page(long page) {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions();
+ return options.page(page);
+ }
+
+ /**
+ * @see ListLoadBalancerRulesOptions#pageSize
+ */
+ public static ListLoadBalancerRulesOptions pageSize(long pageSize) {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions();
+ return options.pageSize(pageSize);
+ }
}
/**
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptions.java
index c9b31f0..5cf580b 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptions.java
@@ -22,27 +22,53 @@
/**
* Options used to control what port forwarding rules are returned
- *
- * @see <a href=
- * "http://download.cloud.com/releases/2.2.0/api/user/listIpForwardingRules.html"
- * />
+ *
* @author Adrian Cole
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/global_admin/listPortForwardingRules.html"
+ * />
*/
public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions();
/**
- * @param IPAddressId
- * list the rule belonging to this public ip address
+ * @param id
+ * lists rule with the specified ID
*/
- public ListPortForwardingRulesOptions IPAddressId(long IPAddressId) {
+ public ListPortForwardingRulesOptions id(long id) {
+ this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
+ return this;
+ }
+
+ /**
+ * @param IPAddressId
+ * list the rule belonging to this public ip address
+ */
+ public ListPortForwardingRulesOptions ipAddressId(long IPAddressId) {
this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(IPAddressId + ""));
return this;
}
public static class Builder {
+
+ /**
+ * @see ListPortForwardingRulesOptions#id
+ */
+ public static ListPortForwardingRulesOptions id(long id) {
+ ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
+ return options.id(id);
+ }
+
+ /**
+ * @see ListPortForwardingRulesOptions#ipAddressId
+ */
+ public static ListPortForwardingRulesOptions ipAddressId(long ipAddressId) {
+ ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
+ return options.ipAddressId(ipAddressId);
+ }
+
/**
* @see ListPortForwardingRulesOptions#accountInDomain
*/
@@ -52,21 +78,12 @@
}
/**
- * @see ListPortForwardingRulesOptions#IPAddressId
- */
- public static ListPortForwardingRulesOptions IPAddressId(long IPAddressId) {
- ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
- return options.IPAddressId(IPAddressId);
- }
-
- /**
* @see ListPortForwardingRulesOptions#domainId
*/
public static ListPortForwardingRulesOptions domainId(long id) {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.domainId(id);
}
-
}
/**
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotPoliciesOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotPoliciesOptions.java
index 790ba6f..9e36f46 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotPoliciesOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotPoliciesOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotsOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotsOptions.java
index 6a4ef54..11d32e6 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotsOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/ListSnapshotsOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/RegisterISOOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/RegisterISOOptions.java
index e1c5f53..8482e6e 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/RegisterISOOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/RegisterISOOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateISOOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateISOOptions.java
index 1390f01..397c5f4 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateISOOptions.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateISOOptions.java
@@ -1,4 +1,22 @@
/**
+ * 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.
+ */
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateLoadBalancerRuleOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateLoadBalancerRuleOptions.java
new file mode 100644
index 0000000..e2613e1
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateLoadBalancerRuleOptions.java
@@ -0,0 +1,90 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.cloudstack.domain.LoadBalancerRule;
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+import java.util.Set;
+
+/**
+ * Options used to control how a load balancer rule is updated
+ *
+ * @author Andrei Savu
+ * @see <a href=
+ * "http://download.cloud.com/releases/2.2.0/api_2.2.12/user/updateLoadBalancerRule.html"
+ * />
+ */
+public class UpdateLoadBalancerRuleOptions extends BaseHttpRequestOptions {
+
+ public static final UpdateLoadBalancerRuleOptions NONE = new UpdateLoadBalancerRuleOptions();
+
+ /**
+ * @param algorithm load balancer algorithm (source, roundrobin, leastconn)
+ */
+ public UpdateLoadBalancerRuleOptions algorithm(LoadBalancerRule.Algorithm algorithm) {
+ this.queryParameters.replaceValues("algorithm", ImmutableSet.of(algorithm.toString()));
+ return this;
+ }
+
+ /**
+ * @param description the description of the load balancer rule
+ */
+ public UpdateLoadBalancerRuleOptions description(String description) {
+ this.queryParameters.replaceValues("description", ImmutableSet.of(description));
+ return this;
+ }
+
+ /**
+ * @param name the name of the load balancer rule
+ */
+ public UpdateLoadBalancerRuleOptions name(String name) {
+ this.queryParameters.replaceValues("name", ImmutableSet.of(name));
+ return this;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see UpdateLoadBalancerRuleOptions#algorithm
+ */
+ public static UpdateLoadBalancerRuleOptions algorithm(LoadBalancerRule.Algorithm algorithm) {
+ UpdateLoadBalancerRuleOptions options = new UpdateLoadBalancerRuleOptions();
+ return options.algorithm(algorithm);
+ }
+
+ /**
+ * @see UpdateLoadBalancerRuleOptions#description
+ */
+ public static UpdateLoadBalancerRuleOptions description(String description) {
+ UpdateLoadBalancerRuleOptions options = new UpdateLoadBalancerRuleOptions();
+ return options.description(description);
+ }
+
+ /**
+ * @see UpdateLoadBalancerRuleOptions#name
+ */
+ public static UpdateLoadBalancerRuleOptions name(String name) {
+ UpdateLoadBalancerRuleOptions options = new UpdateLoadBalancerRuleOptions();
+ return options.name(name);
+ }
+ }
+}
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkPredicates.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkPredicates.java
index 10119c8..9f69f02 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkPredicates.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkPredicates.java
@@ -93,6 +93,19 @@
}
}
+ private static class DefaultNetworkInZone implements Predicate<Network> {
+ private final long zoneId;
+
+ public DefaultNetworkInZone(long zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ @Override
+ public boolean apply(Network network) {
+ return network.getZoneId() == zoneId && network.isDefault();
+ }
+ }
+
public static class NetworkServiceNamed implements Predicate<NetworkService> {
private final String name;
@@ -190,6 +203,16 @@
}
/**
+ * Filters for default networks in a specific zone.
+ *
+ * @param zoneId the ID of the required zone.
+ * @return networks in the zone that have the default flag set.
+ */
+ public static Predicate<Network> defaultNetworkInZone(final long zoneId) {
+ return new DefaultNetworkInZone(zoneId);
+ }
+
+ /**
*
* @return always returns true.
*/
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ZoneIdToZoneSupplier.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ZoneIdToZoneSupplier.java
new file mode 100644
index 0000000..fd45408
--- /dev/null
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/suppliers/ZoneIdToZoneSupplier.java
@@ -0,0 +1,50 @@
+/**
+ * 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.cloudstack.suppliers;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.inject.Inject;
+import org.jclouds.cloudstack.domain.Zone;
+
+import javax.inject.Named;
+import java.util.concurrent.TimeUnit;
+
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+/**
+ * Supplies a cache that maps from zone IDs to zones.
+ *
+ * @author Richard Downer
+ */
+public class ZoneIdToZoneSupplier implements Supplier<LoadingCache<Long, Zone>> {
+ private final LoadingCache<Long, Zone> cache;
+
+ @Inject
+ public ZoneIdToZoneSupplier(CacheLoader<Long, Zone> zoneIdToZone, @Named(PROPERTY_SESSION_INTERVAL) long expirationSecs) {
+ cache = CacheBuilder.newBuilder().expireAfterWrite(expirationSecs, TimeUnit.SECONDS).build(zoneIdToZone);
+ }
+
+ @Override
+ public LoadingCache<Long, Zone> get() {
+ return cache;
+ }
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/strategy/OptionsConverterTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/strategy/OptionsConverterTest.java
new file mode 100644
index 0000000..af11e90
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/compute/strategy/OptionsConverterTest.java
@@ -0,0 +1,121 @@
+/**
+ * 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.cloudstack.compute.strategy;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.cloudstack.domain.Network;
+import org.jclouds.cloudstack.domain.NetworkService;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test(singleThreaded = true, testName="OptionsConverterTest")
+public class OptionsConverterTest {
+
+ private static final Map<Long,Network> EMPTY_NETWORKS_MAP = Collections.<Long, Network>emptyMap();
+ private static final int ZONE_ID = 2;
+ private final NetworkService firewallServiceWithStaticNat
+ = new NetworkService("Firewall", ImmutableMap.of("StaticNat", "true"));
+
+ @Test
+ public void testBasicNetworkOptionsConverter() {
+ BasicNetworkOptionsConverter converter = new BasicNetworkOptionsConverter();
+
+ CloudStackTemplateOptions optionsIn = CloudStackTemplateOptions.Builder.securityGroupId(42).networkId(46);
+ DeployVirtualMachineOptions optionsOut = new DeployVirtualMachineOptions();
+
+ DeployVirtualMachineOptions optionsOut2 = converter.apply(optionsIn, EMPTY_NETWORKS_MAP, ZONE_ID, optionsOut);
+ assertTrue(optionsOut == optionsOut2);
+
+ DeployVirtualMachineOptions optionsExpected = DeployVirtualMachineOptions.Builder.securityGroupId(42).networkId(46);
+ assertEquals(optionsOut, optionsExpected);
+ }
+
+ @Test
+ public void testAdvancedSecurityGroupsNotAllowed() {
+ boolean exceptionThrown = false;
+ AdvancedNetworkOptionsConverter converter = new AdvancedNetworkOptionsConverter();
+ CloudStackTemplateOptions optionsIn = CloudStackTemplateOptions.Builder.securityGroupId(42);
+
+ try {
+ converter.apply(optionsIn, EMPTY_NETWORKS_MAP, ZONE_ID, DeployVirtualMachineOptions.NONE);
+ } catch(IllegalArgumentException e) {
+ exceptionThrown = true;
+ }
+
+ assertTrue(exceptionThrown, "IllegalArgumentException should have been thrown");
+ }
+
+ @Test
+ public void testAdvancedExplicitNetworkSelection() {
+ AdvancedNetworkOptionsConverter converter = new AdvancedNetworkOptionsConverter();
+ DeployVirtualMachineOptions optionsActual = converter.apply(CloudStackTemplateOptions.Builder.networkId(42),
+ EMPTY_NETWORKS_MAP, ZONE_ID, DeployVirtualMachineOptions.NONE);
+ DeployVirtualMachineOptions optionsExpected = DeployVirtualMachineOptions.Builder.networkId(42);
+ assertEquals(optionsActual, optionsExpected);
+ }
+
+ @Test
+ public void testAdvancedAutoDetectNetwork() {
+ AdvancedNetworkOptionsConverter converter = new AdvancedNetworkOptionsConverter();
+
+ Network eligibleNetwork = Network.builder()
+ .id(25).zoneId(ZONE_ID).isDefault(true).services(ImmutableSet.of(firewallServiceWithStaticNat))
+ .build();
+ DeployVirtualMachineOptions optionsActual = converter.apply(CloudStackTemplateOptions.NONE,
+ ImmutableMap.of(eligibleNetwork.getId(), eligibleNetwork), ZONE_ID, DeployVirtualMachineOptions.NONE);
+ DeployVirtualMachineOptions optionsExpected = DeployVirtualMachineOptions.Builder.networkId(25);
+ assertEquals(optionsActual, optionsExpected);
+ }
+
+ @Test
+ public void testAdvancedWhenNoNetworkGiven() {
+ AdvancedNetworkOptionsConverter converter = new AdvancedNetworkOptionsConverter();
+ boolean exceptionThrown = false;
+ try {
+ converter.apply(CloudStackTemplateOptions.NONE, EMPTY_NETWORKS_MAP, ZONE_ID, DeployVirtualMachineOptions.NONE);
+ } catch(IllegalArgumentException e) {
+ exceptionThrown = true;
+ }
+ assertTrue(exceptionThrown);
+ }
+
+ @Test
+ public void testAdvancedWhenNoNetworkEligible() {
+ AdvancedNetworkOptionsConverter converter = new AdvancedNetworkOptionsConverter();
+ Network unsuitableNetwork = Network.builder()
+ .id(25).zoneId(ZONE_ID)
+ .build();
+
+ boolean exceptionThrown = false;
+ try {
+ converter.apply(CloudStackTemplateOptions.NONE, ImmutableMap.of(unsuitableNetwork.getId(), unsuitableNetwork), ZONE_ID, DeployVirtualMachineOptions.NONE);
+ } catch(IllegalArgumentException e) {
+ exceptionThrown = true;
+ }
+ assertTrue(exceptionThrown);
+ }
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientExpectTest.java
new file mode 100644
index 0000000..93f0b1b
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientExpectTest.java
@@ -0,0 +1,114 @@
+/**
+ * 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.cloudstack.features;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Set;
+
+import org.jclouds.cloudstack.CloudStackContext;
+import org.jclouds.cloudstack.domain.Account;
+import org.jclouds.cloudstack.domain.User;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test the CloudStack AccountClient
+ *
+ * @author Andrei Savu
+ */
+@Test(groups = "unit", testName = "AccountClientExpectTest")
+public class AccountClientExpectTest extends BaseCloudStackRestClientExpectTest<AccountClient> {
+
+
+ public void testListAccountsWhenResponseIs2xx() {
+
+ AccountClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=listAccounts&apiKey=identity&signature=maSZcp9ivkL7osVh87qxlrYbZC8%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/listaccountsresponse.json"))
+ .build());
+
+ Set<User> users = ImmutableSet.of(
+ User.builder()
+ .id(505)
+ .name("jclouds")
+ .firstName("Adrian")
+ .lastName("Cole")
+ .email("adrian@jclouds.org")
+ .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-04-19T01:57:24+0000"))
+ .state(User.State.ENABLED)
+ .account("jclouds")
+ .accountType(Account.Type.USER)
+ .domainId(457)
+ .domain("AA000062-jclouds-dev")
+ .apiKey("APIKEY")
+ .secretKey("SECRETKEY").build());
+
+ assertEquals(client.listAccounts(),
+ ImmutableSet.of(Account.builder()
+ .id(505)
+ .name("jclouds")
+ .type(Account.Type.USER)
+ .domainId(457)
+ .domain("AA000062-jclouds-dev")
+ .receivedBytes(318900216)
+ .sentBytes(23189677)
+ .VMLimit(15l)
+ .VMs(1)
+ .IPsAvailable(14l)
+ .IPLimit(15l)
+ .IPs(0)
+ .IPsAvailable(15l)
+ .volumeLimit(90l)
+ .volumes(2)
+ .volumesAvailable(88l)
+ .snapshotLimit(250l)
+ .snapshots(0)
+ .snapshotsAvailable(250l)
+ .templateLimit(15l)
+ .templates(0)
+ .templatesAvailable(15l)
+ .VMsAvailable(14l)
+ .VMsStopped(0)
+ .VMsRunning(1)
+ .state(Account.State.ENABLED)
+ .users(users).build()));
+ }
+
+ @Override
+ protected AccountClient clientFrom(CloudStackContext context) {
+ return context.getProviderSpecificContext().getApi().getAccountClient();
+ }
+}
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackRestClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackRestClientExpectTest.java
new file mode 100644
index 0000000..4f05a35
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/BaseCloudStackRestClientExpectTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.cloudstack.features;
+
+import java.util.Properties;
+
+import org.jclouds.cloudstack.CloudStackContext;
+import org.jclouds.compute.ComputeServiceContextFactory;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.logging.config.NullLoggingModule;
+import org.jclouds.rest.BaseRestClientExpectTest;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * Base class for writing CloudStack Rest Client Expect tests
+ *
+ * @author Andrei Savu
+ */
+public abstract class BaseCloudStackRestClientExpectTest<S> extends BaseRestClientExpectTest<S> {
+
+ public BaseCloudStackRestClientExpectTest() {
+ provider = "cloudstack";
+ }
+
+ @Override
+ public S createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
+ return clientFrom(CloudStackContext.class.cast(new ComputeServiceContextFactory(setupRestProperties())
+ .createContext(provider, "identity", "credential", ImmutableSet.<Module> of(new ExpectModule(fn),
+ new NullLoggingModule(), module), props)));
+ }
+
+ protected abstract S clientFrom(CloudStackContext context);
+
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallAsyncClientTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallAsyncClientTest.java
index a40ff93..1bc2025 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallAsyncClientTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallAsyncClientTest.java
@@ -21,6 +21,7 @@
import java.io.IOException;
import java.lang.reflect.Method;
+import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
@@ -64,7 +65,7 @@
public void testListPortForwardingRulesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = FirewallAsyncClient.class.getMethod("listPortForwardingRules",
ListPortForwardingRulesOptions[].class);
- HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.IPAddressId(3));
+ HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.ipAddressId(3));
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listPortForwardingRules&ipaddressid=3 HTTP/1.1");
@@ -82,12 +83,12 @@
public void testCreatePortForwardingRuleForVirtualMachine() throws SecurityException, NoSuchMethodException,
IOException {
Method method = FirewallAsyncClient.class.getMethod("createPortForwardingRuleForVirtualMachine", long.class,
- long.class, String.class, int.class, int.class);
- HttpRequest httpRequest = processor.createRequest(method, 6, 7, "tcp", 22, 22);
+ PortForwardingRule.Protocol.class, int.class, long.class, int.class);
+ HttpRequest httpRequest = processor.createRequest(method, 6L, PortForwardingRule.Protocol.TCP, 22, 7L, 22);
assertRequestLineEquals(
httpRequest,
- "GET http://localhost:8080/client/api?response=json&command=createPortForwardingRule&virtualmachineid=6&protocol=tcp&ipaddressid=7&privateport=22&publicport=22 HTTP/1.1");
+ "GET http://localhost:8080/client/api?response=json&command=createPortForwardingRule&ipaddressid=6&publicport=22&protocol=tcp&virtualmachineid=7&privateport=22 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientExpectTest.java
new file mode 100644
index 0000000..e663222
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientExpectTest.java
@@ -0,0 +1,315 @@
+/**
+ * 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.cloudstack.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.net.URI;
+import java.util.Set;
+
+import org.jclouds.cloudstack.CloudStackContext;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.FirewallRule;
+import org.jclouds.cloudstack.domain.PortForwardingRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test the CloudStack FirewallClient
+ *
+ * @author Andrei Savu
+ */
+@Test(groups = "unit", testName = "FirewallClientExpectTest")
+public class FirewallClientExpectTest extends BaseCloudStackRestClientExpectTest<FirewallClient> {
+
+ public void testListFirewallRulesWhenResponseIs2xx() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
+ "apiKey=identity&signature=MktZKKH3USVKiC9SlYTSHMCaCcg%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/listfirewallrulesresponse.json"))
+ .build());
+
+ Set<String> CIDRs = ImmutableSet.of("0.0.0.0/0");
+ assertEquals(client.listFirewallRules(),
+ ImmutableSet.of(
+ FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
+ .endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
+ .CIDRs(CIDRs).build(),
+ FirewallRule.builder().id(2016).protocol(FirewallRule.Protocol.TCP).startPort(22)
+ .endPort(22).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
+ .CIDRs(CIDRs).build(),
+ FirewallRule.builder().id(10).protocol(FirewallRule.Protocol.TCP).startPort(22)
+ .endPort(22).ipAddressId(8).ipAddress("10.27.27.57").state(FirewallRule.State.ACTIVE)
+ .CIDRs(CIDRs).build()
+ ));
+ }
+
+ public void testListFirewallRulesWhenReponseIs404() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
+ "apiKey=identity&signature=MktZKKH3USVKiC9SlYTSHMCaCcg%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertEquals(client.listFirewallRules(), ImmutableSet.of());
+ }
+
+ public void testGetFirewallRuleWhenResponseIs2xx() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
+ "id=2017&apiKey=identity&signature=0r5iL%2Bzix9rmD07lJIOhY68mYY0%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/getfirewallrulesresponse.json"))
+ .build());
+
+ assertEquals(client.getFirewallRule(2017),
+ FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
+ .endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE)
+ .CIDRs(ImmutableSet.of("0.0.0.0/0")).build()
+ );
+ }
+
+ public void testGetFirewallRuleWhenResponseIs404() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=listFirewallRules&" +
+ "id=4&apiKey=identity&signature=PPX5U9kmaS116SgG4Ihf8xK%2BcSE%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertNull(client.getFirewallRule(4));
+ }
+
+ public void testCreateFirewallRuleForIpAndProtocol() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=createFirewallRule&" +
+ "ipaddressid=2&protocol=TCP&apiKey=identity&signature=d0MZ%2FyhQPAaV%2BYQmfZsQtQL2C28%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/createfirewallrulesresponse.json"))
+ .build());
+
+ AsyncCreateResponse response = client.createFirewallRuleForIpAndProtocol(2, FirewallRule.Protocol.TCP);
+ assertEquals(response.getJobId(), 2036);
+ assertEquals(response.getId(), 2017);
+ }
+
+ public void testDeleteFirewallRule() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=deleteFirewallRule&id=2015&apiKey=identity&signature=%2FT5FAO2yGPctaPmg7TEtIEFW3EU%3D"))
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/deletefirewallrulesresponse.json"))
+ .build());
+
+ client.deleteFirewallRule(2015);
+ }
+
+ public void testListPortForwardingRulesWhenResponseIs2xx() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listPortForwardingRules&apiKey=identity&signature=YFBu1VOSkiDKxm0K42sIXJWy%2BBo%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/listportforwardingrulesresponse.json"))
+ .build());
+
+ Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
+
+ assertEquals(client.listPortForwardingRules(),
+ ImmutableSet.<PortForwardingRule>of(
+ PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
+ .publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
+ .IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build(),
+ PortForwardingRule.builder().id(18).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
+ .publicPort(22).virtualMachineId(89).virtualMachineName("i-3-89-VM").IPAddressId(34)
+ .IPAddress("72.52.126.63").state(PortForwardingRule.State.ACTIVE).build())
+ );
+ }
+
+ public void testListPortForwardingRulesWhenReponseIs404() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listPortForwardingRules&apiKey=identity&signature=YFBu1VOSkiDKxm0K42sIXJWy%2BBo%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertEquals(client.listPortForwardingRules(), ImmutableSet.of());
+ }
+
+ public void testGetPortForwardingRuleWhenResponseIs2xx() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listPortForwardingRules&id=15&apiKey=identity&signature=ABJsciF4n2tXaiyUmEvc3oYh9MA%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/getportforwardingrulesresponse.json"))
+ .build());
+
+ Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
+
+ assertEquals(client.getPortForwardingRule(15),
+ PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
+ .publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
+ .IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build());
+ }
+
+ public void testGetPortForwardingRuleWhenResponseIs404() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listPortForwardingRules&id=4&apiKey=identity&signature=CTOmmIOGIiZx0YATqh%2FFk0zIplw%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertNull(client.getPortForwardingRule(4));
+ }
+
+ public void testCreatePortForwardingRuleForVirtualMachine() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&command=createPortForwardingRule&" +
+ "ipaddressid=2&publicport=22&protocol=tcp&virtualmachineid=1234&privateport=22&" +
+ "apiKey=identity&signature=84dtGzQp0G6k3z3Gkc3F%2FHBNS2Y%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/createportforwardingrulesresponse.json"))
+ .build());
+
+ AsyncCreateResponse response = client.createPortForwardingRuleForVirtualMachine(
+ 2, PortForwardingRule.Protocol.TCP, 22, 1234, 22);
+ assertEquals(response.getJobId(), 2035);
+ assertEquals(response.getId(), 2015);
+ }
+
+ public void testDeletePortForwardingRule() {
+ FirewallClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=deletePortForwardingRule&id=2015&apiKey=identity&signature=2UE7KB3wm5ocmR%2BGMNFKPKfiDo8%3D"))
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/deleteportforwardingrulesresponse.json"))
+ .build());
+
+ client.deletePortForwardingRule(2015);
+ }
+
+ @Override
+ protected FirewallClient clientFrom(CloudStackContext context) {
+ return context.getProviderSpecificContext().getApi().getFirewallClient();
+ }
+}
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientLiveTest.java
index 4ea0345..836e414 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/FirewallClientLiveTest.java
@@ -19,18 +19,22 @@
package org.jclouds.cloudstack.features;
import static com.google.common.collect.Iterables.find;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsPortForwarding;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException;
import java.util.Set;
+import com.google.common.base.Predicates;
import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.VirtualMachine;
-import org.jclouds.cloudstack.predicates.NetworkPredicates;
+import org.jclouds.cloudstack.options.CreateFirewallRuleOptions;
+import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
@@ -38,16 +42,21 @@
import com.google.common.base.Predicate;
+import javax.annotation.Nullable;
+
/**
* Tests behavior of {@code FirewallClientLiveTest}
- *
+ *
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "FirewallClientLiveTest")
public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null;
private VirtualMachine vm;
- private PortForwardingRule rule;
+
+ private FirewallRule firewallRule;
+ private PortForwardingRule portForwardingRule;
+
private Network network;
private boolean networksDisabled;
@@ -56,13 +65,25 @@
super.setupClient();
prefix += "rule";
try {
- network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.supportsPortForwarding());
+ network = find(client.getNetworkClient().listNetworks(), Predicates.and(supportsPortForwarding(),
+ new Predicate<Network>() {
+ @Override
+ public boolean apply(@Nullable Network network) {
+ return network.isDefault()
+ && !network.isSecurityGroupEnabled()
+ && network.getAccount().equals(user.getAccount());
+ }
+ }));
+
Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
+
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network,
- defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete,
- virtualMachineRunning);
+ defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
+ client, jobComplete, virtualMachineRunning);
+
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
+
} catch (NoSuchElementException e) {
networksDisabled = true;
}
@@ -71,30 +92,75 @@
public void testCreatePortForwardingRule() throws Exception {
if (networksDisabled)
return;
- while (rule == null) {
+ while (portForwardingRule == null) {
ip = reuseOrAssociate.apply(network);
try {
- AsyncCreateResponse job = client.getFirewallClient().createPortForwardingRuleForVirtualMachine(vm.getId(),
- ip.getId(), "tcp", 22, 22);
+ AsyncCreateResponse job = client.getFirewallClient()
+ .createPortForwardingRuleForVirtualMachine(ip.getId(), PortForwardingRule.Protocol.TCP, 22, vm.getId(), 22);
assertTrue(jobComplete.apply(job.getJobId()));
- rule = findRuleWithId(job.getId());
+ portForwardingRule = client.getFirewallClient().getPortForwardingRule(job.getId());
+
} catch (IllegalStateException e) {
+ Logger.CONSOLE.error("Failed while trying to allocate ip: " + e);
// very likely an ip conflict, so retry;
}
}
- assertEquals(rule.getIPAddressId(), ip.getId());
- assertEquals(rule.getVirtualMachineId(), vm.getId());
- assertEquals(rule.getPublicPort(), 22);
- assertEquals(rule.getProtocol(), "tcp");
- checkRule(rule);
+ assertEquals(portForwardingRule.getIPAddressId(), ip.getId());
+ assertEquals(portForwardingRule.getVirtualMachineId(), vm.getId());
+ assertEquals(portForwardingRule.getPublicPort(), 22);
+ assertEquals(portForwardingRule.getProtocol(), "tcp");
+
+ checkPortForwardingRule(portForwardingRule);
checkSSH(new IPSocket(ip.getIPAddress(), 22));
}
+ @Test(dependsOnMethods = "testCreatePortForwardingRule")
+ public void testListPortForwardingRules() throws Exception {
+ Set<PortForwardingRule> response = client.getFirewallClient().listPortForwardingRules();
+ assert null != response;
+ assertTrue(response.size() >= 0);
+ for (final PortForwardingRule rule : response) {
+ checkPortForwardingRule(rule);
+ }
+ }
+
+ @Test(dependsOnMethods = "testCreatePortForwardingRule")
+ public void testCreateFirewallRule() {
+ if (networksDisabled)
+ return;
+
+ AsyncCreateResponse job = client.getFirewallClient().createFirewallRuleForIpAndProtocol(
+ ip.getId(), FirewallRule.Protocol.TCP, CreateFirewallRuleOptions.Builder.startPort(30).endPort(35));
+ assertTrue(jobComplete.apply(job.getJobId()));
+ firewallRule = client.getFirewallClient().getFirewallRule(job.getId());
+
+ assertEquals(firewallRule.getStartPort(), 30);
+ assertEquals(firewallRule.getEndPort(), 35);
+ assertEquals(firewallRule.getProtocol(), FirewallRule.Protocol.TCP);
+
+ checkFirewallRule(firewallRule);
+ }
+
+ @Test(dependsOnMethods = "testCreateFirewallRule")
+ public void testListFirewallRules() {
+ Set<FirewallRule> rules = client.getFirewallClient().listFirewallRules();
+
+ assert rules != null;
+ assertTrue(rules.size() > 0);
+
+ for(FirewallRule rule : rules) {
+ checkFirewallRule(rule);
+ }
+ }
+
@AfterGroups(groups = "live")
protected void tearDown() {
- if (rule != null) {
- client.getFirewallClient().deletePortForwardingRule(rule.getId());
+ if (firewallRule != null) {
+ client.getFirewallClient().deleteFirewallRule(firewallRule.getId());
+ }
+ if (portForwardingRule != null) {
+ client.getFirewallClient().deletePortForwardingRule(portForwardingRule.getId());
}
if (vm != null) {
jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
@@ -105,30 +171,18 @@
super.tearDown();
}
- public void testListPortForwardingRules() throws Exception {
- Set<PortForwardingRule> response = client.getFirewallClient().listPortForwardingRules();
- assert null != response;
- assertTrue(response.size() >= 0);
- for (final PortForwardingRule rule : response) {
- PortForwardingRule newDetails = findRuleWithId(rule.getId());
- assertEquals(rule.getId(), newDetails.getId());
- checkRule(rule);
- }
+ protected void checkFirewallRule(FirewallRule rule) {
+ assertEquals(rule,
+ client.getFirewallClient().getFirewallRule(rule.getId()));
+ assert rule.getId() > 0 : rule;
+ assert rule.getStartPort() > 0 : rule;
+ assert rule.getEndPort() >= rule.getStartPort() : rule;
+ assert rule.getProtocol() != null;
}
- private PortForwardingRule findRuleWithId(final long id) {
- return find(client.getFirewallClient().listPortForwardingRules(), new Predicate<PortForwardingRule>() {
-
- @Override
- public boolean apply(PortForwardingRule arg0) {
- return arg0.getId() == id;
- }
-
- });
- }
-
- protected void checkRule(PortForwardingRule rule) {
- assertEquals(rule.getId(), findRuleWithId(rule.getId()).getId());
+ protected void checkPortForwardingRule(PortForwardingRule rule) {
+ assertEquals(rule,
+ client.getFirewallClient().getPortForwardingRule(rule.getId()));
assert rule.getId() > 0 : rule;
assert rule.getIPAddress() != null : rule;
assert rule.getIPAddressId() > 0 : rule;
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientExpectTest.java
new file mode 100644
index 0000000..913f021
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientExpectTest.java
@@ -0,0 +1,147 @@
+/**
+ * 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.cloudstack.features;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import org.jclouds.cloudstack.CloudStackClient;
+import org.jclouds.cloudstack.CloudStackContext;
+import org.jclouds.cloudstack.CloudStackGlobalClient;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.domain.ConfigurationEntry;
+import org.jclouds.cloudstack.domain.FirewallRule;
+import org.jclouds.cloudstack.domain.PortForwardingRule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.util.Set;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+/**
+ * Test the CloudStack GlobalConfigurationClient
+ *
+ * @author Andrei Savu
+ */
+@Test(groups = "unit", testName = "GlobalConfigurationClientExpectTest")
+public class GlobalConfigurationClientExpectTest extends BaseCloudStackRestClientExpectTest<GlobalConfigurationClient> {
+
+ @Test
+ public void testListConfigurationEntriesWhenResponseIs2xx() {
+ GlobalConfigurationClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listConfigurations&apiKey=identity&signature=FUQCDbc4TH2S%2B7ExDgrOCqKI2bw%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/listconfigurationsresponse.json"))
+ .build());
+
+ assertEquals(client.listConfigurationEntries(),
+ ImmutableSet.of(
+ ConfigurationEntry.builder().category("Advanced").name("account.cleanup.interval").value("86400")
+ .description("The interval (in seconds) between cleanup for removed accounts").build(),
+ ConfigurationEntry.builder().category("Advanced").name("agent.lb.enabled").value("true")
+ .description("If agent load balancing enabled in cluster setup").build()
+ ));
+ }
+
+ @Test
+ public void testListConfigurationEntriesEmptyOn404() {
+ GlobalConfigurationClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=listConfigurations&apiKey=identity&signature=FUQCDbc4TH2S%2B7ExDgrOCqKI2bw%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertEquals(client.listConfigurationEntries(), ImmutableSet.of());
+ }
+
+ @Test
+ public void testUpdateConfigurationEntryWhenResponseIs2xx() {
+ GlobalConfigurationClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=updateConfiguration&name=expunge.delay&value=11&" +
+ "apiKey=identity&signature=I2yG35EhfgIXYObeLfU3cvf%2BPeE%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/updateconfigurationsresponse.json"))
+ .build());
+
+ assertEquals(client.updateConfigurationEntry("expunge.delay", "11"),
+ ConfigurationEntry.builder().category("Advanced").name("expunge.delay").value("11")
+ .description("Determines how long (in seconds) to wait before actually expunging " +
+ "destroyed vm. The default value = the default value of expunge.interval").build()
+ );
+ }
+
+ @Test
+ public void testUpdateConfigurationEntryNullOn404() {
+ GlobalConfigurationClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=updateConfiguration&name=expunge.delay&value=11&" +
+ "apiKey=identity&signature=I2yG35EhfgIXYObeLfU3cvf%2BPeE%3D"))
+ .headers(
+ ImmutableMultimap.<String, String>builder()
+ .put("Accept", "application/json")
+ .build())
+ .build(),
+ HttpResponse.builder()
+ .statusCode(404)
+ .build());
+
+ assertNull(client.updateConfigurationEntry("expunge.delay", "11"));
+ }
+
+ @Override
+ protected GlobalConfigurationClient clientFrom(CloudStackContext context) {
+ return context.getGlobalContext().getApi().getConfigurationClient();
+ }
+}
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientLiveTest.java
new file mode 100644
index 0000000..2ad890f
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalConfigurationClientLiveTest.java
@@ -0,0 +1,102 @@
+/**
+ * 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.cloudstack.features;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import org.jclouds.cloudstack.domain.ConfigurationEntry;
+import org.testng.annotations.Test;
+import org.testng.collections.Sets;
+
+import javax.annotation.Nullable;
+import java.util.Set;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static org.jclouds.cloudstack.options.ListConfigurationEntriesOptions.Builder.name;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests behavior of {@code GlobalConfigurationClient}
+ *
+ * @author Andrei Savu
+ */
+@Test(groups = "live", singleThreaded = true, testName = "GlobalConfigurationClientLiveTest")
+public class GlobalConfigurationClientLiveTest extends BaseCloudStackClientLiveTest {
+
+ @Test
+ public void testListConfigurationEntries() {
+ assert globalAdminEnabled;
+
+ Set<ConfigurationEntry> entries = globalAdminClient
+ .getConfigurationClient().listConfigurationEntries();
+
+ Set<String> categories = Sets.newHashSet();
+ for (ConfigurationEntry entry : entries) {
+ checkConfigurationEntry(entry);
+ categories.add(entry.getCategory());
+ }
+
+ assert categories.containsAll(ImmutableSet.<Object>of("Network", "Advanced", "Premium",
+ "Storage", "Usage", "Snapshots", "Account Defaults", "Console Proxy", "Alert"));
+ }
+
+ @Test
+ public void testUpdateConfigurationEntry() {
+ assert globalAdminEnabled;
+
+ Set<ConfigurationEntry> entries = globalAdminClient
+ .getConfigurationClient().listConfigurationEntries();
+
+ long expungeDelay = Long.parseLong(getValueByName(entries, "expunge.delay"));
+ assert expungeDelay > 0;
+
+ globalAdminClient.getConfigurationClient()
+ .updateConfigurationEntry("expunge.delay", "" + (expungeDelay + 1));
+
+ long newDelay = Long.parseLong(getOnlyElement(globalAdminClient.getConfigurationClient()
+ .listConfigurationEntries(name("expunge.delay"))).getValue());
+ assertEquals(newDelay, expungeDelay + 1);
+
+ globalAdminClient.getConfigurationClient()
+ .updateConfigurationEntry("expunge.delay", "" + expungeDelay);
+ }
+
+ private void checkConfigurationEntry(ConfigurationEntry entry) {
+ assertEquals(entry, getEntryByName(globalAdminClient.getConfigurationClient()
+ .listConfigurationEntries(name(entry.getName())), entry.getName()));
+ assert entry.getCategory() != null : entry;
+ assert entry.getDescription() != null : entry;
+ assert entry.getName() != null : entry;
+ }
+
+ private String getValueByName(Set<ConfigurationEntry> entries, String name) {
+ return getEntryByName(entries, name).getValue();
+ }
+
+ private ConfigurationEntry getEntryByName(Set<ConfigurationEntry> entries, final String name) {
+ return Iterables.find(entries, new Predicate<ConfigurationEntry>() {
+ @Override
+ public boolean apply(@Nullable ConfigurationEntry entry) {
+ return entry != null && Objects.equal(name, entry.getName());
+ }
+ });
+ }
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientLiveTest.java
index 7764ca8..cab4014 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientLiveTest.java
@@ -18,10 +18,13 @@
*/
package org.jclouds.cloudstack.features;
+import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import java.util.Set;
+import com.google.common.base.Strings;
+import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host;
import org.testng.annotations.Test;
@@ -61,4 +64,29 @@
}
}
+ @Test(groups = "live", enabled = true)
+ public void testListClusters() throws Exception {
+ assertTrue(globalAdminEnabled, "Test cannot run without global admin identity and credentials");
+
+ Set<Cluster> clusters = globalAdminClient.getHostClient().listClusters();
+ assert clusters.size() > 0 : clusters;
+
+ for(Cluster cluster : clusters) {
+ checkCluster(cluster);
+ }
+ }
+
+ private void checkCluster(Cluster cluster) {
+ assertTrue(cluster.getId() > 0);
+ assertFalse(Strings.isNullOrEmpty(cluster.getName()));
+ assertTrue(cluster.getAllocationState() != Host.AllocationState.UNKNOWN);
+ assertTrue(cluster.getClusterType() != Host.ClusterType.UNKNOWN);
+ assertFalse(Strings.isNullOrEmpty(cluster.getHypervisor()));
+ assertTrue(cluster.getManagedState() != Cluster.ManagedState.UNRECOGNIZED);
+ assertTrue(cluster.getPodId() > 0);
+ assertFalse(Strings.isNullOrEmpty(cluster.getPodName()));
+ assertTrue(cluster.getZoneId() > 0);
+ assertFalse(Strings.isNullOrEmpty(cluster.getZoneName()));
+ }
+
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClientTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClientTest.java
index 48b9278..a44842a 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClientTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClientTest.java
@@ -22,7 +22,9 @@
import java.lang.reflect.Method;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
+import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
+import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
@@ -80,7 +82,7 @@
public void testCreateLoadBalancerRuleForPublicIP() throws SecurityException, NoSuchMethodException, IOException {
Method method = LoadBalancerAsyncClient.class.getMethod("createLoadBalancerRuleForPublicIP", long.class,
- Algorithm.class, String.class, int.class, int.class);
+ Algorithm.class, String.class, int.class, int.class, CreateLoadBalancerRuleOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, 6, Algorithm.LEASTCONN, "tcp", 22, 22);
assertRequestLineEquals(
@@ -97,6 +99,22 @@
}
+ public void testUpdateLoadBalancerRule() throws SecurityException, NoSuchMethodException, IOException {
+ Method method = LoadBalancerAsyncClient.class.getMethod("updateLoadBalancerRule", long.class, UpdateLoadBalancerRuleOptions[].class);
+ HttpRequest httpRequest = processor.createRequest(method, 5);
+
+ assertRequestLineEquals(httpRequest,
+ "GET http://localhost:8080/client/api?response=json&command=updateLoadBalancerRule&id=5 HTTP/1.1");
+ assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
+ assertPayloadEquals(httpRequest, null, null, false);
+
+ assertSaxResponseParserClassEquals(method, null);
+ assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
+
+ checkFilters(httpRequest);
+
+ }
+
public void testDeleteLoadBalancerRule() throws SecurityException, NoSuchMethodException, IOException {
Method method = LoadBalancerAsyncClient.class.getMethod("deleteLoadBalancerRule", long.class);
HttpRequest httpRequest = processor.createRequest(method, 5);
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java
index 01931d7..4d258e8 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java
@@ -19,6 +19,8 @@
package org.jclouds.cloudstack.features;
import static com.google.common.collect.Iterables.find;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.hasLoadBalancerService;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.isVirtualNetwork;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -48,6 +50,8 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import javax.annotation.Nullable;
+
/**
* Tests behavior of {@code LoadBalancerClientLiveTest}
*
@@ -71,7 +75,16 @@
prefix += "rule";
try {
network = find(client.getNetworkClient().listNetworks(),
- Predicates.and(NetworkPredicates.hasLoadBalancerService(), NetworkPredicates.isVirtualNetwork()));
+ Predicates.and(hasLoadBalancerService(), isVirtualNetwork(),
+ new Predicate<Network>() {
+ @Override
+ public boolean apply(@Nullable Network network) {
+ return network.isDefault()
+ && !network.isSecurityGroupEnabled()
+ && !network.isSystem()
+ && network.getAccount().equals(user.getName());
+ }
+ }));
} catch (NoSuchElementException e) {
networksDisabled = true;
}
@@ -82,8 +95,8 @@
return;
Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network,
- defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete,
- virtualMachineRunning);
+ defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
+ client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java
index ffec261..eb4ec13 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/OfferingClientLiveTest.java
@@ -64,7 +64,7 @@
} catch (NoSuchElementException e) {
// This bug is present both in 2.2.8 and 2.2.12
- assertTrue("2.2.8".equals(apiversion) || "2.2.12".equals(apiversion));
+ assertTrue("2.2.8".equals(apiVersion) || "2.2.12".equals(apiVersion));
}
}
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
index 3f355d2..fd44fd9 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java
@@ -31,6 +31,7 @@
import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.AccountInDomainOptions;
+import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.net.IPSocket;
import org.jclouds.util.Strings2;
@@ -195,6 +196,23 @@
assert group.getIngressRules() != null : group;
}
+ @Test
+ public void testCreateVMWithoutSecurityGroupAssignsDefault() throws Exception {
+ if (!securityGroupsSupported)
+ return;
+ Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
+ VirtualMachine newVm = VirtualMachineClientLiveTest.createVirtualMachineWithOptionsInZone(DeployVirtualMachineOptions.NONE,
+ zone.getId(), defaultTemplateOrPreferredInZone(defaultTemplate, client, zone.getId()), client,
+ jobComplete, virtualMachineRunning);
+ try {
+ VirtualMachine runningVm = client.getVirtualMachineClient().getVirtualMachine(newVm.getId());
+ assertTrue(runningVm.getSecurityGroups().size() == 1);
+ assertEquals(Iterables.getOnlyElement(runningVm.getSecurityGroups()).getName(), "default");
+ } finally {
+ assertTrue(jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(newVm.getId())));
+ }
+ }
+
@AfterGroups(groups = "live")
protected void tearDown() {
if (vm != null) {
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/filters/QuerySignerTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/filters/QuerySignerTest.java
index c2d09ef..2e75496 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/filters/QuerySignerTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/filters/QuerySignerTest.java
@@ -21,17 +21,17 @@
import static org.testng.Assert.assertEquals;
import java.net.URI;
-import java.util.List;
-import java.util.Map;
import org.jclouds.PropertiesBuilder;
import org.jclouds.http.HttpRequest;
+import org.jclouds.http.IntegrationTestAsyncClient;
+import org.jclouds.http.IntegrationTestClient;
import org.jclouds.logging.config.NullLoggingModule;
-import org.jclouds.rest.BaseRestClientTest.MockModule;
import org.jclouds.rest.RequestSigner;
import org.jclouds.rest.RestContextBuilder;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
+import org.jclouds.rest.BaseRestClientTest.MockModule;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
@@ -48,8 +48,8 @@
@Test(groups = "unit", testName = "QuerySignerTest")
public class QuerySignerTest {
@SuppressWarnings({ "unchecked", "rawtypes" })
- public static final RestContextSpec<Map, List> DUMMY_SPEC = new RestContextSpec<Map, List>("cloudstack",
- "http://localhost:8080/client/api", "2.2", "", "apiKey", "secretKey", Map.class, List.class,
+ public static final RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> DUMMY_SPEC = new RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient>("cloudstack",
+ "http://localhost:8080/client/api", "2.2", "", "", "apiKey", "secretKey", IntegrationTestClient.class, IntegrationTestAsyncClient.class,
PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList.<Module> of(new MockModule(),
new NullLoggingModule(), new AbstractModule() {
@Override
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListClustersOptionsTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListClustersOptionsTest.java
new file mode 100644
index 0000000..502fa6f
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListClustersOptionsTest.java
@@ -0,0 +1,126 @@
+/**
+ * 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.cloudstack.options;
+
+import com.google.common.collect.ImmutableList;
+import org.jclouds.cloudstack.domain.Cluster;
+import org.jclouds.cloudstack.domain.Host;
+import org.testng.annotations.Test;
+
+import static org.jclouds.cloudstack.options.ListClustersOptions.Builder.*;
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Tests behavior of {@code ListClustersOptions}
+ *
+ * @author Richard Downer
+ */
+@Test(groups = "unit")
+public class ListClustersOptionsTest {
+
+ public void testAllocationState() {
+ ListClustersOptions options = new ListClustersOptions().allocationState(Host.AllocationState.ENABLED);
+ assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("allocationstate"));
+ }
+
+ public void testAllocationStateStatic() {
+ ListClustersOptions options = allocationState(Host.AllocationState.ENABLED);
+ assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("allocationstate"));
+ }
+
+ public void testClusterType() {
+ ListClustersOptions options = new ListClustersOptions().clusterType(Host.ClusterType.CLOUD_MANAGED);
+ assertEquals(ImmutableList.of("CloudManaged"), options.buildQueryParameters().get("clustertype"));
+ }
+
+ public void testClusterTypeStatic() {
+ ListClustersOptions options = clusterType(Host.ClusterType.CLOUD_MANAGED);
+ assertEquals(ImmutableList.of("CloudManaged"), options.buildQueryParameters().get("clustertype"));
+ }
+
+ public void testHypervisor() {
+ ListClustersOptions options = new ListClustersOptions().hypervisor("XenServer");
+ assertEquals(ImmutableList.of("XenServer"), options.buildQueryParameters().get("hypervisor"));
+ }
+
+ public void testHypervisorStatic() {
+ ListClustersOptions options = hypervisor("XenServer");
+ assertEquals(ImmutableList.of("XenServer"), options.buildQueryParameters().get("hypervisor"));
+ }
+
+ public void testId() {
+ ListClustersOptions options = new ListClustersOptions().id(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("id"));
+ }
+
+ public void testIdStatic() {
+ ListClustersOptions options = id(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("id"));
+ }
+
+ public void testKeyword() {
+ ListClustersOptions options = new ListClustersOptions().keyword("Enabled");
+ assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("keyword"));
+ }
+
+ public void testKeywordStatic() {
+ ListClustersOptions options = keyword("Enabled");
+ assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("keyword"));
+ }
+
+ public void testManagedState() {
+ ListClustersOptions options = new ListClustersOptions().managedState(Cluster.ManagedState.PREPARE_UNMANAGED);
+ assertEquals(ImmutableList.of("PrepareUnmanaged"), options.buildQueryParameters().get("managedstate"));
+ }
+
+ public void testManagedStateStatic() {
+ ListClustersOptions options = managedState(Cluster.ManagedState.PREPARE_UNMANAGED);
+ assertEquals(ImmutableList.of("PrepareUnmanaged"), options.buildQueryParameters().get("managedstate"));
+ }
+
+ public void testName() {
+ ListClustersOptions options = new ListClustersOptions().name("Host Name");
+ assertEquals(ImmutableList.of("Host Name"), options.buildQueryParameters().get("name"));
+ }
+
+ public void testNameStatic() {
+ ListClustersOptions options = name("Host Name");
+ assertEquals(ImmutableList.of("Host Name"), options.buildQueryParameters().get("name"));
+ }
+
+ public void testPodId() {
+ ListClustersOptions options = new ListClustersOptions().podId(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("podid"));
+ }
+
+ public void testPodIdStatic() {
+ ListClustersOptions options = podId(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("podid"));
+ }
+
+ public void testZoneId() {
+ ListClustersOptions options = new ListClustersOptions().zoneId(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("zoneid"));
+ }
+
+ public void testZoneIdStatic() {
+ ListClustersOptions options = zoneId(42L);
+ assertEquals(ImmutableList.of("42"), options.buildQueryParameters().get("zoneid"));
+ }
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptionsTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptionsTest.java
index 7f0f1b4..51ee772 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptionsTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListLoadBalancerRulesOptionsTest.java
@@ -22,8 +22,11 @@
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.domainId;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.id;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.name;
+import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.page;
+import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.pageSize;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.publicIPId;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.virtualMachineId;
+import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.zoneId;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@@ -32,7 +35,7 @@
/**
* Tests behavior of {@code ListLoadBalancerRulesOptions}
- *
+ *
* @author Adrian Cole
*/
@Test(groups = "unit")
@@ -99,4 +102,34 @@
ListLoadBalancerRulesOptions options = virtualMachineId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("virtualmachineid"));
}
+
+ public void testZoneId() {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions().zoneId(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("zoneid"));
+ }
+
+ public void testZoneIdStatic() {
+ ListLoadBalancerRulesOptions options = zoneId(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("zoneid"));
+ }
+
+ public void testPage() {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions().page(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("page"));
+ }
+
+ public void testPageStatic() {
+ ListLoadBalancerRulesOptions options = page(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("page"));
+ }
+
+ public void testPageSize() {
+ ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions().pageSize(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("pagesize"));
+ }
+
+ public void testPageSizeStatic() {
+ ListLoadBalancerRulesOptions options = pageSize(6);
+ assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("pagesize"));
+ }
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptionsTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptionsTest.java
index 66a4020..595e8f9 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptionsTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/ListPortForwardingRulesOptionsTest.java
@@ -18,9 +18,9 @@
*/
package org.jclouds.cloudstack.options;
-import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.IPAddressId;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.accountInDomain;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.domainId;
+import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.ipAddressId;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@@ -48,12 +48,12 @@
}
public void testName() {
- ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().IPAddressId(9);
+ ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
}
public void testNameStatic() {
- ListPortForwardingRulesOptions options = IPAddressId(9);
+ ListPortForwardingRulesOptions options = ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListClustersResponseTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListClustersResponseTest.java
new file mode 100644
index 0000000..8f6354b
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListClustersResponseTest.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.cloudstack.parse;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.jclouds.cloudstack.config.CloudStackParserModule;
+import org.jclouds.cloudstack.domain.Cluster;
+import org.jclouds.cloudstack.domain.Host;
+import org.jclouds.date.internal.SimpleDateFormatDateService;
+import org.jclouds.json.BaseSetParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import java.util.Set;
+
+/**
+ * @author Richard Downer
+ */
+@Test(groups = "unit")
+public class ListClustersResponseTest extends BaseSetParserTest<Cluster> {
+
+ @Override
+ public String resource() {
+ return "/listclustersresponse.json";
+ }
+
+ @Override
+ @SelectJson("cluster")
+ public Set<Cluster> expected() {
+ Cluster cluster1 = Cluster.builder()
+ .id(1)
+ .name("Xen Clust 1")
+ .podId(1).podName("Dev Pod 1")
+ .zoneId(1).zoneName("Dev Zone 1")
+ .hypervisor("XenServer")
+ .clusterType(Host.ClusterType.CLOUD_MANAGED)
+ .allocationState(Host.AllocationState.ENABLED)
+ .managedState(Cluster.ManagedState.MANAGED)
+ .build();
+ Cluster cluster2 = Cluster.builder()
+ .id(2)
+ .name("Xen Clust 1")
+ .podId(2).podName("Dev Pod 2")
+ .zoneId(2).zoneName("Dev Zone 2")
+ .hypervisor("XenServer")
+ .clusterType(Host.ClusterType.CLOUD_MANAGED)
+ .allocationState(Host.AllocationState.ENABLED)
+ .managedState(Cluster.ManagedState.MANAGED)
+ .build();
+
+ return ImmutableSet.of(cluster1, cluster2);
+ }
+
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListConfigurationEntriesResponseTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListConfigurationEntriesResponseTest.java
new file mode 100644
index 0000000..0a734a9
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListConfigurationEntriesResponseTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.cloudstack.parse;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.jclouds.cloudstack.config.CloudStackParserModule;
+import org.jclouds.cloudstack.domain.ConfigurationEntry;
+import org.jclouds.cloudstack.domain.FirewallRule;
+import org.jclouds.json.BaseSetParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import java.util.Set;
+
+/**
+ * @author Andrei Savu
+ */
+@Test(groups = "unit")
+public class ListConfigurationEntriesResponseTest extends BaseSetParserTest<ConfigurationEntry> {
+
+ @Override
+ protected Injector injector() {
+ return Guice.createInjector(new CloudStackParserModule(), new GsonModule() {
+
+ @Override
+ protected void configure() {
+ bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+ super.configure();
+ }
+
+ });
+ }
+
+ @Override
+ public String resource() {
+ return "/listconfigurationsresponse.json";
+ }
+
+ @Override
+ @SelectJson("configuration")
+ public Set<ConfigurationEntry> expected() {
+ return ImmutableSet.of(
+ ConfigurationEntry.builder().category("Advanced").name("account.cleanup.interval").value("86400")
+ .description("The interval (in seconds) between cleanup for removed accounts").build(),
+ ConfigurationEntry.builder().category("Advanced").name("agent.lb.enabled").value("true")
+ .description("If agent load balancing enabled in cluster setup").build()
+ );
+ }
+
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListFirewallRulesResponseTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListFirewallRulesResponseTest.java
new file mode 100644
index 0000000..1a67ca3
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListFirewallRulesResponseTest.java
@@ -0,0 +1,72 @@
+/**
+ * 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.cloudstack.parse;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.jclouds.cloudstack.config.CloudStackParserModule;
+import org.jclouds.cloudstack.domain.FirewallRule;
+import org.jclouds.json.BaseSetParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import java.util.Set;
+
+/**
+ *
+ * @author Andrei Savu
+ */
+@Test(groups = "unit")
+public class ListFirewallRulesResponseTest extends BaseSetParserTest<FirewallRule> {
+
+ @Override
+ protected Injector injector() {
+ return Guice.createInjector(new CloudStackParserModule(), new GsonModule() {
+
+ @Override
+ protected void configure() {
+ bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+ super.configure();
+ }
+
+ });
+ }
+
+ @Override
+ public String resource() {
+ return "/listfirewallrulesresponse.json";
+ }
+
+ @Override
+ @SelectJson("firewallrule")
+ public Set<FirewallRule> expected() {
+ Set<String> CIDRs = ImmutableSet.of("0.0.0.0/0");
+ return ImmutableSet.of(
+ FirewallRule.builder().id(2017).protocol(FirewallRule.Protocol.TCP).startPort(30)
+ .endPort(35).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build(),
+ FirewallRule.builder().id(2016).protocol(FirewallRule.Protocol.TCP).startPort(22)
+ .endPort(22).ipAddressId(2).ipAddress("10.27.27.51").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build(),
+ FirewallRule.builder().id(10).protocol(FirewallRule.Protocol.TCP).startPort(22)
+ .endPort(22).ipAddressId(8).ipAddress("10.27.27.57").state(FirewallRule.State.ACTIVE).CIDRs(CIDRs).build()
+ );
+ }
+
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListPortForwardingRulesResponseTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListPortForwardingRulesResponseTest.java
index 85b41e6..5079c7c 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListPortForwardingRulesResponseTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/parse/ListPortForwardingRulesResponseTest.java
@@ -61,10 +61,12 @@
public Set<PortForwardingRule> expected() {
Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
return ImmutableSet.<PortForwardingRule> of(
- PortForwardingRule.builder().id(15).privatePort(22).protocol("tcp").publicPort(2022).virtualMachineId(3)
- .virtualMachineName("i-3-3-VM").IPAddressId(3).IPAddress("72.52.126.32").state("Active").CIDRs(cidrs).build(),
- PortForwardingRule.builder().id(18).privatePort(22).protocol("tcp").publicPort(22).virtualMachineId(89)
- .virtualMachineName("i-3-89-VM").IPAddressId(34).IPAddress("72.52.126.63").state("Active").build());
+ PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
+ .publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
+ .IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build(),
+ PortForwardingRule.builder().id(18).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
+ .publicPort(22).virtualMachineId(89).virtualMachineName("i-3-89-VM").IPAddressId(34)
+ .IPAddress("72.52.126.63").state(PortForwardingRule.State.ACTIVE).build());
}
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/NetworkPredicatesTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/NetworkPredicatesTest.java
index effd125..9ff6b8f 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/NetworkPredicatesTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/NetworkPredicatesTest.java
@@ -18,10 +18,7 @@
*/
package org.jclouds.cloudstack.predicates;
-import static org.jclouds.cloudstack.predicates.NetworkPredicates.hasLoadBalancerService;
-import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsPortForwarding;
-import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsStaticNAT;
-
+import com.google.common.base.Predicate;
import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkService;
import org.testng.annotations.Test;
@@ -30,6 +27,10 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import static org.jclouds.cloudstack.predicates.NetworkPredicates.*;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
/**
*
* @author Adrian Cole
@@ -93,4 +94,17 @@
assert !hasLoadBalancerService().apply(network);
}
+
+ public void testDefaultNetworkInZone() {
+ Network defaultInZone = Network.builder().isDefault(true).zoneId(42).build();
+ Network defaultNotInZone = Network.builder().isDefault(true).zoneId(200).build();
+ Network notDefaultInZone = Network.builder().isDefault(false).zoneId(42).build();
+ Network notDefaultNotInZone = Network.builder().isDefault(false).zoneId(200).build();
+
+ Predicate<Network> predicate = defaultNetworkInZone(42);
+ assertTrue(predicate.apply(defaultInZone));
+ assertFalse(predicate.apply(defaultNotInZone));
+ assertFalse(predicate.apply(notDefaultInZone));
+ assertFalse(predicate.apply(notDefaultNotInZone));
+ }
}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/TemplatePredicatesTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/TemplatePredicatesTest.java
index a98aedb..7f92319 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/TemplatePredicatesTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/TemplatePredicatesTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.predicates;
import org.jclouds.cloudstack.domain.Template;
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/UserPredicatesTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/UserPredicatesTest.java
index 4fe137a..74b8e68 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/UserPredicatesTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/UserPredicatesTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.predicates;
import org.jclouds.cloudstack.domain.Account;
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/ZonePredicatesTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/ZonePredicatesTest.java
index 0486521..561fce0 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/ZonePredicatesTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/predicates/ZonePredicatesTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudstack.predicates;
import org.jclouds.cloudstack.domain.NetworkType;
diff --git a/apis/cloudstack/src/test/resources/createfirewallrulesresponse.json b/apis/cloudstack/src/test/resources/createfirewallrulesresponse.json
new file mode 100644
index 0000000..f6a727b
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/createfirewallrulesresponse.json
@@ -0,0 +1 @@
+{ "createfirewallruleresponse" : {"jobid":2036,"id":2017} }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/createportforwardingrulesresponse.json b/apis/cloudstack/src/test/resources/createportforwardingrulesresponse.json
new file mode 100644
index 0000000..cf29e1c
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/createportforwardingrulesresponse.json
@@ -0,0 +1 @@
+{ "createportforwardingruleresponse" : {"jobid":2035,"id":2015} }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/deletefirewallrulesresponse.json b/apis/cloudstack/src/test/resources/deletefirewallrulesresponse.json
new file mode 100644
index 0000000..abf5b6d
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/deletefirewallrulesresponse.json
@@ -0,0 +1 @@
+{ "deletefirewallruleresponse" : {"jobid":2037} }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/deleteportforwardingrulesresponse.json b/apis/cloudstack/src/test/resources/deleteportforwardingrulesresponse.json
new file mode 100644
index 0000000..552ad94
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/deleteportforwardingrulesresponse.json
@@ -0,0 +1 @@
+{ "deleteportforwardingruleresponse" : {"jobid":2038} }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/getfirewallrulesresponse.json b/apis/cloudstack/src/test/resources/getfirewallrulesresponse.json
new file mode 100644
index 0000000..88d3d47
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/getfirewallrulesresponse.json
@@ -0,0 +1,2 @@
+{ "listfirewallrulesresponse" : { "count":1 ,"firewallrule" : [
+ {"id":2017,"protocol":"tcp","startport":"30","endport":"35","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"} ] } }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/getportforwardingrulesresponse.json b/apis/cloudstack/src/test/resources/getportforwardingrulesresponse.json
new file mode 100644
index 0000000..3ea044d
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/getportforwardingrulesresponse.json
@@ -0,0 +1,2 @@
+{ "listportforwardingrulesresponse" : { "portforwardingrule" : [
+ {"id":15,"privateport":"22","protocol":"tcp","publicport":"2022","virtualmachineid":3,"virtualmachinename":"i-3-3-VM","ipaddressid":3,"ipaddress":"72.52.126.32","state":"Active","cidrlist":"0.0.0.0/1,128.0.0.0/1"} ] } }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/listclustersresponse.json b/apis/cloudstack/src/test/resources/listclustersresponse.json
new file mode 100644
index 0000000..64dd052
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/listclustersresponse.json
@@ -0,0 +1 @@
+{ "listclustersresponse" : { "count":2 ,"cluster" : [ {"id":1,"name":"Xen Clust 1","podid":1,"podname":"Dev Pod 1","zoneid":1,"zonename":"Dev Zone 1","hypervisortype":"XenServer","clustertype":"CloudManaged","allocationstate":"Enabled","managedstate":"Managed"}, {"id":2,"name":"Xen Clust 1","podid":2,"podname":"Dev Pod 2","zoneid":2,"zonename":"Dev Zone 2","hypervisortype":"XenServer","clustertype":"CloudManaged","allocationstate":"Enabled","managedstate":"Managed"} ] } }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/listconfigurationsresponse.json b/apis/cloudstack/src/test/resources/listconfigurationsresponse.json
new file mode 100644
index 0000000..25bc7a1
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/listconfigurationsresponse.json
@@ -0,0 +1,4 @@
+{ "listconfigurationsresponse" : { "count":2 ,"configuration" : [
+ {"category":"Advanced","name":"account.cleanup.interval","value":"86400","description":"The interval (in seconds) between cleanup for removed accounts"},
+ {"category":"Advanced","name":"agent.lb.enabled","value":"true","description":"If agent load balancing enabled in cluster setup"}]
+}}
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/listfirewallrulesresponse.json b/apis/cloudstack/src/test/resources/listfirewallrulesresponse.json
new file mode 100644
index 0000000..e93d76e
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/listfirewallrulesresponse.json
@@ -0,0 +1,4 @@
+{ "listfirewallrulesresponse" : { "count":3 ,"firewallrule" : [
+ {"id":2017,"protocol":"tcp","startport":"30","endport":"35","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"},
+ {"id":2016,"protocol":"tcp","startport":"22","endport":"22","ipaddressid":2,"ipaddress":"10.27.27.51","state":"Active","cidrlist":"0.0.0.0/0"},
+ {"id":10,"protocol":"tcp","startport":"22","endport":"22","ipaddressid":8,"ipaddress":"10.27.27.57","state":"Active","cidrlist":"0.0.0.0/0"} ] } }
\ No newline at end of file
diff --git a/apis/cloudstack/src/test/resources/updateconfigurationsresponse.json b/apis/cloudstack/src/test/resources/updateconfigurationsresponse.json
new file mode 100644
index 0000000..6013bd5
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/updateconfigurationsresponse.json
@@ -0,0 +1,2 @@
+{ "updateconfigurationresponse" : { "configuration" :
+ {"category":"Advanced","name":"expunge.delay","value":"11","description":"Determines how long (in seconds) to wait before actually expunging destroyed vm. The default value = the default value of expunge.interval"} } }
\ No newline at end of file
diff --git a/apis/cloudwatch/pom.xml b/apis/cloudwatch/pom.xml
index bf0b2aa..559236a 100644
--- a/apis/cloudwatch/pom.xml
+++ b/apis/cloudwatch/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudwatch.endpoint>https://monitoring.us-east-1.amazonaws.com</test.cloudwatch.endpoint>
- <test.cloudwatch.apiversion>2009-05-15</test.cloudwatch.apiversion>
+ <test.cloudwatch.api-version>2009-05-15</test.cloudwatch.api-version>
+ <test.cloudwatch.build-version></test.cloudwatch.build-version>
<test.cloudwatch.identity>${test.aws.identity}</test.cloudwatch.identity>
<test.cloudwatch.credential>${test.aws.credential}</test.cloudwatch.credential>
</properties>
@@ -86,7 +87,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudwatch.endpoint>${test.cloudwatch.endpoint}</test.cloudwatch.endpoint>
- <test.cloudwatch.apiversion>${test.cloudwatch.apiversion}</test.cloudwatch.apiversion>
+ <test.cloudwatch.api-version>${test.cloudwatch.api-version}</test.cloudwatch.api-version>
+ <test.cloudwatch.build-version>${test.cloudwatch.build-version}</test.cloudwatch.build-version>
<test.cloudwatch.identity>${test.cloudwatch.identity}</test.cloudwatch.identity>
<test.cloudwatch.credential>${test.cloudwatch.credential}</test.cloudwatch.credential>
</systemPropertyVariables>
diff --git a/apis/cloudwatch/src/main/java/org/jclouds/cloudwatch/domain/Statistics.java b/apis/cloudwatch/src/main/java/org/jclouds/cloudwatch/domain/Statistics.java
index 6405a05..b44b5f3 100644
--- a/apis/cloudwatch/src/main/java/org/jclouds/cloudwatch/domain/Statistics.java
+++ b/apis/cloudwatch/src/main/java/org/jclouds/cloudwatch/domain/Statistics.java
@@ -1,3 +1,21 @@
+/**
+ * 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.cloudwatch.domain;
import com.google.common.base.CaseFormat;
diff --git a/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchClientLiveTest.java b/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchClientLiveTest.java
index 5b27763..672eaea 100644
--- a/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchClientLiveTest.java
+++ b/apis/cloudwatch/src/test/java/org/jclouds/cloudwatch/CloudWatchClientLiveTest.java
@@ -25,12 +25,12 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
+import org.jclouds.rest.BaseRestClientLiveTest;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterTest;
@@ -45,37 +45,15 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class CloudWatchClientLiveTest {
+@Test(groups = "live", singleThreaded = true)
+public class CloudWatchClientLiveTest extends BaseRestClientLiveTest {
+ public CloudWatchClientLiveTest() {
+ provider = "cloudwatch";
+ }
private CloudWatchClient client;
private RestContext<CloudWatchClient, CloudWatchAsyncClient> context;
- protected String provider = "cloudwatch";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint", null);
- apiversion = System.getProperty("test." + provider + ".apiversion", null);
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/deltacloud/pom.xml b/apis/deltacloud/pom.xml
index 6b52075..7b8e438 100644
--- a/apis/deltacloud/pom.xml
+++ b/apis/deltacloud/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.deltacloud.endpoint>http://localhost:3001/api</test.deltacloud.endpoint>
- <test.deltacloud.apiversion>0.3.0</test.deltacloud.apiversion>
+ <test.deltacloud.api-version>0.3.0</test.deltacloud.api-version>
+ <test.deltacloud.build-version></test.deltacloud.build-version>
<test.deltacloud.identity>mockuser</test.deltacloud.identity>
<test.deltacloud.credential>mockpassword</test.deltacloud.credential>
<test.deltacloud.image-id />
@@ -107,7 +108,8 @@
<configuration>
<systemPropertyVariables>
<test.deltacloud.endpoint>${test.deltacloud.endpoint}</test.deltacloud.endpoint>
- <test.deltacloud.apiversion>${test.deltacloud.apiversion}</test.deltacloud.apiversion>
+ <test.deltacloud.api-version>${test.deltacloud.api-version}</test.deltacloud.api-version>
+ <test.deltacloud.build-version>${test.deltacloud.build-version}</test.deltacloud.build-version>
<test.deltacloud.identity>${test.deltacloud.identity}</test.deltacloud.identity>
<test.deltacloud.credential>${test.deltacloud.credential}</test.deltacloud.credential>
<test.deltacloud.image-id>${test.deltacloud.image-id}</test.deltacloud.image-id>
diff --git a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java
index 30061ef..10ed812 100644
--- a/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java
+++ b/apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java
@@ -26,7 +26,7 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile;
@@ -59,40 +59,19 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true, testName = "ReadOnlyDeltacloudClientLiveTest")
-public class ReadOnlyDeltacloudClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "ReadOnlyDeltacloudClientLiveTest")
+public class ReadOnlyDeltacloudClientLiveTest extends BaseVersionedServiceLiveTest {
+ public ReadOnlyDeltacloudClientLiveTest() {
+ provider = "deltacloud";
+ }
protected DeltacloudClient client;
protected RestContext<DeltacloudClient, DeltacloudAsyncClient> context;
- protected String provider = "deltacloud";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
+
protected Predicate<IPSocket> socketTester;
protected ImmutableMap<State, Predicate<Instance>> stateChanges;
- protected void setupCredentials() {
- identity = System.getProperty("test." + provider + ".identity", "mockuser");
- credential = System.getProperty("test." + provider + ".credential", "mockpassword");
- endpoint = System.getProperty("test." + provider + ".endpoint", "http://localhost:3001/api");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = "live")
public void setupClient() {
diff --git a/apis/ec2/pom.xml b/apis/ec2/pom.xml
index 7b0823a..4132100 100644
--- a/apis/ec2/pom.xml
+++ b/apis/ec2/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.ec2.endpoint>https://ec2.us-east-1.amazonaws.com</test.ec2.endpoint>
- <test.ec2.apiversion>2010-06-15</test.ec2.apiversion>
+ <test.ec2.api-version>2010-06-15</test.ec2.api-version>
+ <test.ec2.build-version></test.ec2.build-version>
<test.ec2.identity>${test.aws.identity}</test.ec2.identity>
<test.ec2.credential>${test.aws.credential}</test.ec2.credential>
<test.ec2.image-id />
@@ -102,7 +103,8 @@
<configuration>
<systemPropertyVariables>
<test.ec2.endpoint>${test.ec2.endpoint}</test.ec2.endpoint>
- <test.ec2.apiversion>${test.ec2.apiversion}</test.ec2.apiversion>
+ <test.ec2.api-version>${test.ec2.api-version}</test.ec2.api-version>
+ <test.ec2.build-version>${test.ec2.build-version}</test.ec2.build-version>
<test.ec2.identity>${test.ec2.identity}</test.ec2.identity>
<test.ec2.credential>${test.ec2.credential}</test.ec2.credential>
<test.ec2.image-id>${test.ec2.image-id}</test.ec2.image-id>
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
index 463f56e..a974767 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java
@@ -56,8 +56,6 @@
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.reference.EC2Constants;
import org.jclouds.predicates.RetryablePredicate;
-import org.jclouds.rest.RestContext;
-import org.jclouds.rest.internal.RestContextImpl;
import com.google.common.base.Function;
import com.google.common.base.Functions;
@@ -112,9 +110,6 @@
bind(new TypeLiteral<ComputeServiceContext>() {
}).to(new TypeLiteral<ComputeServiceContextImpl<EC2Client, EC2AsyncClient>>() {
}).in(Scopes.SINGLETON);
- bind(new TypeLiteral<RestContext<EC2Client, EC2AsyncClient>>() {
- }).to(new TypeLiteral<RestContextImpl<EC2Client, EC2AsyncClient>>() {
- }).in(Scopes.SINGLETON);
}
/**
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
index 6e67abc..88842af 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
@@ -96,6 +96,7 @@
@SuppressWarnings("unchecked")
@Override
public Future<Set<? extends Reservation<? extends RunningInstance>>> apply(String from) {
+ // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7126754
return castToSpecificTypedFuture(client.getInstanceServices().describeInstancesInRegion(from));
}
@@ -104,7 +105,6 @@
return concat(concat(reservations));
}
- // "hide" this cast (i.e. do not perform inline) from the Java 7 compiler - see http://stackoverflow.com/questions/8637937/why-does-a-generic-cast-of-a-list-extends-set-to-listset-succeed-on-sun
@SuppressWarnings("unchecked")
private static <T> Future<T> castToSpecificTypedFuture(Future<? extends T> input) {
return (Future<T>) input;
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
index 1d6adc9..7223131 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermission.java
@@ -46,14 +46,6 @@
/**
* List of security group and user ID pairs.
- *
- * @see #getUserIdGroupPairs
- */
- @Deprecated
- Set<UserIdGroupPair> getGroups();
-
- /**
- * List of security group and user ID pairs.
*/
Multimap<String, String> getUserIdGroupPairs();
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermissionImpl.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermissionImpl.java
index 7de47ee..fe80198 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermissionImpl.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/IpPermissionImpl.java
@@ -20,7 +20,6 @@
import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Map.Entry;
import java.util.Set;
import com.google.common.collect.ImmutableMultimap;
@@ -144,18 +143,6 @@
* {@inheritDoc}
*/
@Override
- @Deprecated
- public Set<UserIdGroupPair> getGroups() {
- ImmutableSet.Builder<UserIdGroupPair> groups = ImmutableSet.<UserIdGroupPair> builder();
- for (Entry<String, String> pair : userIdGroupPairs.entries())
- groups.add(new UserIdGroupPair(pair.getKey(), pair.getValue()));
- return groups.build();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public Multimap<String, String> getUserIdGroupPairs() {
return userIdGroupPairs;
}
diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/KeyPair.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/KeyPair.java
index 0038838..ead73cb 100644
--- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/KeyPair.java
+++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/KeyPair.java
@@ -80,7 +80,7 @@
}
public static Builder fromKeyPair(KeyPair in) {
- return new Builder().region(in.getRegion()).keyName(in.getKeyName()).sha1OfPrivateKey(in.getKeyFingerprint())
+ return new Builder().region(in.getRegion()).keyName(in.getKeyName()).sha1OfPrivateKey(in.getSha1OfPrivateKey())
.keyMaterial(in.getKeyMaterial());
}
}
@@ -117,14 +117,6 @@
}
/**
- * @see #getSha1OfPrivateKey
- */
- @Deprecated
- public String getKeyFingerprint() {
- return sha1OfPrivateKey;
- }
-
- /**
* A SHA-1 digest of the DER encoded private key.
*
* @see SshKeys#sha1
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
index 8243cf2..a007730 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/CloudApplicationArchitecturesEC2ClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.ec2;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
import static org.testng.Assert.assertEquals;
@@ -34,12 +33,11 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import org.jclouds.Constants;
import org.jclouds.aws.AWSResponseException;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.domain.BlockDevice;
-import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.IpProtocol;
@@ -47,6 +45,7 @@
import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.Image.EbsBlockDevice;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.predicates.InstanceHasIpAddress;
import org.jclouds.ec2.predicates.InstanceStateRunning;
@@ -80,8 +79,11 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", enabled = false, sequential = true)
-public class CloudApplicationArchitecturesEC2ClientLiveTest {
+@Test(groups = "live", enabled = false, singleThreaded = true, testName = "CloudApplicationArchitecturesEC2ClientLiveTest")
+public class CloudApplicationArchitecturesEC2ClientLiveTest extends BaseVersionedServiceLiveTest {
+ public CloudApplicationArchitecturesEC2ClientLiveTest() {
+ provider = "ec2";
+ }
private EC2Client client;
protected SshClient.Factory sshFactory;
@@ -95,32 +97,6 @@
private RetryablePredicate<RunningInstance> hasIpTester;
private RetryablePredicate<RunningInstance> runningTester;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
index 7d27d65..04819b5 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.ec2;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.ec2.options.CreateSnapshotOptions.Builder.withDescription;
import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.withKernelId;
@@ -34,15 +33,13 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import org.jclouds.Constants;
import org.jclouds.aws.AWSResponseException;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image;
-import org.jclouds.ec2.domain.Image.Architecture;
-import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.domain.InstanceState;
import org.jclouds.ec2.domain.InstanceType;
import org.jclouds.ec2.domain.IpProtocol;
@@ -52,6 +49,8 @@
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.ec2.domain.Snapshot;
import org.jclouds.ec2.domain.Volume;
+import org.jclouds.ec2.domain.Image.Architecture;
+import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
import org.jclouds.ec2.predicates.InstanceStateRunning;
import org.jclouds.ec2.predicates.InstanceStateStopped;
@@ -95,13 +94,19 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", enabled = false, sequential = true)
-public class EBSBootEC2ClientLiveTest {
+@Test(groups = "live", enabled = false, singleThreaded = true, testName = "EBSBootEC2ClientLiveTest")
+public class EBSBootEC2ClientLiveTest extends BaseVersionedServiceLiveTest {
+ public EBSBootEC2ClientLiveTest() {
+ provider = "ec2";
+ }
+
+ // TODO: parameterize
+ private static final String IMAGE_ID = "ami-7e28ca17";
+
// don't need a lot of space. 2GB should be more than enough for testing
private static final int VOLUME_SIZE = 2;
private static final String SCRIPT_END = "----COMPLETE----";
private static final String INSTANCE_PREFIX = System.getProperty("user.name") + ".ec2ebs";
- private static final String IMAGE_ID = "ami-7e28ca17";
private EC2Client client;
private SshClient.Factory sshFactory;
@@ -124,32 +129,6 @@
private Attachment attachment;
private String mkEbsBoot;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
index 1c9a977..48cf8c5 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
@@ -18,11 +18,14 @@
*/
package org.jclouds.ec2.compute;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-import com.google.common.base.Splitter;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
@@ -50,7 +53,6 @@
import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.services.SecurityGroupClient;
-import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.scriptbuilder.domain.Statements;
@@ -66,8 +68,6 @@
import com.google.common.collect.Sets;
import com.google.inject.Module;
-import static org.testng.Assert.*;
-
/**
*
* @author Adrian Cole
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
index 9e4ed92..6495c88 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.ec2.compute;
import static org.jclouds.http.internal.TrackingJavaUrlHttpCommandExecutorService.getJavaArgsForRequestAtIndex;
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java
index c6e6eea..1e80331 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java
@@ -18,13 +18,11 @@
*/
package org.jclouds.ec2.compute;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
@@ -32,7 +30,6 @@
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -44,37 +41,13 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class TestCanRecreateGroupLiveTest {
+@Test(groups = "live", testName="TestCanRecreateGroupLiveTest")
+public class TestCanRecreateGroupLiveTest extends BaseVersionedServiceLiveTest {
+ public TestCanRecreateGroupLiveTest() {
+ provider = "ec2";
+ }
private ComputeServiceContext context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() throws FileNotFoundException, IOException {
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java
index 329a678..8c7eb90 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AvailabilityZoneAndRegionClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.ec2.options.DescribeAvailabilityZonesOptions.Builder.availabilityZones;
import static org.jclouds.ec2.options.DescribeRegionsOptions.Builder.regions;
import static org.testng.Assert.assertEquals;
@@ -26,13 +25,13 @@
import java.net.URI;
import java.util.Iterator;
-import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
+import java.util.Map.Entry;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -40,7 +39,6 @@
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -54,38 +52,14 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class AvailabilityZoneAndRegionClientLiveTest {
-
+@Test(groups = "live", singleThreaded = true, testName = "AvailabilityZoneAndRegionClientLiveTest")
+public class AvailabilityZoneAndRegionClientLiveTest extends BaseVersionedServiceLiveTest {
+ public AvailabilityZoneAndRegionClientLiveTest() {
+ provider = "ec2";
+ }
+
private AvailabilityZoneAndRegionClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java
index 79bc671..4655c5f 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticBlockStoreClientLiveTest.java
@@ -30,6 +30,7 @@
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -57,39 +58,16 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class ElasticBlockStoreClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "ElasticBlockStoreClientLiveTest")
+public class ElasticBlockStoreClientLiveTest extends BaseVersionedServiceLiveTest {
+ public ElasticBlockStoreClientLiveTest() {
+ provider = "ec2";
+ }
+
private ElasticBlockStoreClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
private String volumeId;
private Snapshot snapshot;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java
index 4391984..d35074b 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/ElasticIPAddressClientLiveTest.java
@@ -18,15 +18,14 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.Properties;
import java.util.SortedSet;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -47,38 +46,15 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class ElasticIPAddressClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "ElasticIPAddressClientLiveTest")
+public class ElasticIPAddressClientLiveTest extends BaseVersionedServiceLiveTest {
+ public ElasticIPAddressClientLiveTest() {
+ provider = "ec2";
+ }
private ElasticIPAddressClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java
index 4cb4044..9a4d9f0 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceClientLiveTest.java
@@ -18,14 +18,13 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull;
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -46,37 +45,15 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class InstanceClientLiveTest {
- public static final String PREFIX = System.getProperty("user.name") + "-ec2";
+@Test(groups = "live", singleThreaded = true, testName = "InstanceClientLiveTest")
+public class InstanceClientLiveTest extends BaseVersionedServiceLiveTest {
+ public InstanceClientLiveTest() {
+ provider = "ec2";
+ }
private InstanceClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
+
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java
index 3107404..a0d3b86 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/KeyPairClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -26,8 +25,8 @@
import java.util.Set;
import java.util.SortedSet;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -48,37 +47,15 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class KeyPairClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "KeyPairClientLiveTest")
+public class KeyPairClientLiveTest extends BaseVersionedServiceLiveTest {
+ public KeyPairClientLiveTest() {
+ provider = "ec2";
+ }
private KeyPairClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
index 9372710..5ff0d10 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/SecurityGroupClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -27,8 +26,8 @@
import java.util.Set;
import java.util.SortedSet;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
@@ -55,39 +54,15 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", singleThreaded = true)
-public class SecurityGroupClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "SecurityGroupClientLiveTest")
+public class SecurityGroupClientLiveTest extends BaseVersionedServiceLiveTest {
+ public SecurityGroupClientLiveTest() {
+ provider = "ec2";
+ }
protected SecurityGroupClient client;
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java
index 67ec283..a11244e 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/WindowsClientLiveTest.java
@@ -18,14 +18,12 @@
*/
package org.jclouds.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.util.Properties;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
+import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
-import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeGroups;
@@ -39,8 +37,11 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class WindowsClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "WindowsClientLiveTest")
+public class WindowsClientLiveTest extends BaseVersionedServiceLiveTest {
+ public WindowsClientLiveTest() {
+ provider = "ec2";
+ }
private WindowsClient client;
private static final String DEFAULT_INSTANCE = "i-TODO";
@@ -48,31 +49,6 @@
private RestContext<EC2Client, EC2AsyncClient> context;
- protected String provider = "ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/apis/elasticstack/pom.xml b/apis/elasticstack/pom.xml
index fe9d113..c51c596 100644
--- a/apis/elasticstack/pom.xml
+++ b/apis/elasticstack/pom.xml
@@ -49,12 +49,13 @@
<properties>
<test.elasticstack.endpoint>https://api.lon-p.elastichosts.com</test.elasticstack.endpoint>
- <test.elasticstack.apiversion>1.0</test.elasticstack.apiversion>
+ <test.elasticstack.api-version>1.0</test.elasticstack.api-version>
+ <test.elasticstack.build-version></test.elasticstack.build-version>
<test.elasticstack.identity>FIXME</test.elasticstack.identity>
<test.elasticstack.credential>FIXME</test.elasticstack.credential>
- <test.elasticstack.image-id />
- <test.elasticstack.image.login-user />
- <test.elasticstack.image.authenticate-sudo />
+ <test.elasticstack.image-id>38df0986-4d85-4b76-b502-3878ffc80161</test.elasticstack.image-id>
+ <test.elasticstack.image.login-user></test.elasticstack.image.login-user>
+ <test.elasticstack.image.authenticate-sudo></test.elasticstack.image.authenticate-sudo>
</properties>
<dependencies>
<dependency>
@@ -107,7 +108,8 @@
<configuration>
<systemPropertyVariables>
<test.elasticstack.endpoint>${test.elasticstack.endpoint}</test.elasticstack.endpoint>
- <test.elasticstack.apiversion>${test.elasticstack.apiversion}</test.elasticstack.apiversion>
+ <test.elasticstack.api-version>${test.elasticstack.api-version}</test.elasticstack.api-version>
+ <test.elasticstack.build-version>${test.elasticstack.build-version}</test.elasticstack.build-version>
<test.elasticstack.identity>${test.elasticstack.identity}</test.elasticstack.identity>
<test.elasticstack.credential>${test.elasticstack.credential}</test.elasticstack.credential>
<test.elasticstack.image-id>${test.elasticstack.image-id}</test.elasticstack.image-id>
diff --git a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java
index d7bc885..43f35ae 100644
--- a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java
+++ b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.elasticstack;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -28,7 +27,8 @@
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
+import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.LoginCredentials;
@@ -60,6 +60,7 @@
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
@@ -71,57 +72,39 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class ElasticStackClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "ElasticStackClientLiveTest")
+public class ElasticStackClientLiveTest extends BaseVersionedServiceLiveTest {
+ public ElasticStackClientLiveTest() {
+ provider = "elasticstack";
+ }
protected long driveSize = 1 * 1024 * 1024 * 1024l;
protected int maxDriveImageTime = 360;
protected String vncPassword = "Il0veVNC";
protected ElasticStackClient client;
+ protected ComputeServiceContext computeContext;
protected RestContext<ElasticStackClient, ElasticStackAsyncClient> context;
protected Predicate<IPSocket> socketTester;
- protected String bootDrive = "38df0986-4d85-4b76-b502-3878ffc80161";
-
- protected String provider = "elasticstack";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected Predicate<DriveInfo> driveNotClaimed;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = "live")
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
- context = new ComputeServiceContextFactory().createContext(provider,
- ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
-
+ computeContext = new ComputeServiceContextFactory().createContext(provider,
+ ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides);
+ context = computeContext.getProviderSpecificContext();
+
client = context.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS);
+
+ if (Strings.emptyToNull(imageId) == null) {
+ imageId = computeContext.getComputeService().templateBuilder().build().getImage().getId();
+ }
}
@Test
@@ -377,7 +360,7 @@
protected void prepareDrive() {
System.err.println("before prepare" + client.getDriveInfo(drive.getUuid()));
- client.imageDrive(bootDrive, drive.getUuid(), ImageConversionType.GUNZIP);
+ client.imageDrive(imageId, drive.getUuid(), ImageConversionType.GUNZIP);
assert driveNotClaimed.apply(drive) : client.getDriveInfo(drive.getUuid());
System.err.println("after prepare" + client.getDriveInfo(drive.getUuid()));
}
diff --git a/apis/eucalyptus/pom.xml b/apis/eucalyptus/pom.xml
index 7c2f0d7..92dc68f 100644
--- a/apis/eucalyptus/pom.xml
+++ b/apis/eucalyptus/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.eucalyptus.endpoint>http://ecc.eucalyptus.com:8773/services/Eucalyptus</test.eucalyptus.endpoint>
- <test.eucalyptus.apiversion>2010-06-15</test.eucalyptus.apiversion>
+ <test.eucalyptus.api-version>2010-06-15</test.eucalyptus.api-version>
+ <test.eucalyptus.build-version></test.eucalyptus.build-version>
<test.eucalyptus.identity>FIXME_IDENTITY</test.eucalyptus.identity>
<test.eucalyptus.credential>FIXME_CREDENTIAL</test.eucalyptus.credential>
<test.eucalyptus.image-id />
@@ -102,7 +103,8 @@
<configuration>
<systemPropertyVariables>
<test.eucalyptus.endpoint>${test.eucalyptus.endpoint}</test.eucalyptus.endpoint>
- <test.eucalyptus.apiversion>${test.eucalyptus.apiversion}</test.eucalyptus.apiversion>
+ <test.eucalyptus.api-version>${test.eucalyptus.api-version}</test.eucalyptus.api-version>
+ <test.eucalyptus.build-version>${test.eucalyptus.build-version}</test.eucalyptus.build-version>
<test.eucalyptus.identity>${test.eucalyptus.identity}</test.eucalyptus.identity>
<test.eucalyptus.credential>${test.eucalyptus.credential}</test.eucalyptus.credential>
<test.eucalyptus.image-id>${test.eucalyptus.image-id}</test.eucalyptus.image-id>
diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemTestInitializer.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemTestInitializer.java
index 9522730..12fbb61 100644
--- a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemTestInitializer.java
+++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemTestInitializer.java
@@ -44,17 +44,18 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
+ new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
}
@Override
- protected Properties setupProperties(String endpoint, String apiversion, String identity, String credential) {
- Properties props = super.setupProperties(endpoint, apiversion, identity, credential);
+ protected Properties setupProperties(String endpoint, String apiVersion, String buildVersion, String identity,
+ String credential) {
+ Properties props = super.setupProperties(endpoint, apiVersion, buildVersion, identity, credential);
props.setProperty(FilesystemConstants.PROPERTY_BASEDIR, TestUtils.TARGET_BASE_DIR);
return props;
}
-}
\ No newline at end of file
+}
diff --git a/apis/nova/pom.xml b/apis/nova/pom.xml
index 7ad5eb4..e052dec 100644
--- a/apis/nova/pom.xml
+++ b/apis/nova/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.nova.endpoint>http://localhost:8773/services/Cloud</test.nova.endpoint>
- <test.nova.apiversion>1.1</test.nova.apiversion>
+ <test.nova.api-version>1.1</test.nova.api-version>
+ <test.nova.build-version></test.nova.build-version>
<test.nova.identity>FIXME_IDENTITY</test.nova.identity>
<test.nova.credential>FIXME_CREDENTIALS</test.nova.credential>
<test.nova.image-id />
@@ -115,7 +116,8 @@
<configuration>
<systemPropertyVariables>
<test.nova.endpoint>${test.nova.endpoint}</test.nova.endpoint>
- <test.nova.apiversion>${test.nova.apiversion}</test.nova.apiversion>
+ <test.nova.api-version>${test.nova.api-version}</test.nova.api-version>
+ <test.nova.build-version>${test.nova.build-version}</test.nova.build-version>
<test.nova.identity>${test.nova.identity}</test.nova.identity>
<test.nova.credential>${test.nova.credential}</test.nova.credential>
<test.nova.image-id>${test.nova.image-id}</test.nova.image-id>
diff --git a/apis/nova/src/main/java/org/jclouds/openstack/nova/config/NovaRestClientModule.java b/apis/nova/src/main/java/org/jclouds/openstack/nova/config/NovaRestClientModule.java
index 03934f4..205eb74 100644
--- a/apis/nova/src/main/java/org/jclouds/openstack/nova/config/NovaRestClientModule.java
+++ b/apis/nova/src/main/java/org/jclouds/openstack/nova/config/NovaRestClientModule.java
@@ -27,6 +27,7 @@
import org.jclouds.openstack.nova.ServerManagement;
import org.jclouds.openstack.nova.handlers.ParseNovaErrorFromHttpResponse;
import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@@ -35,6 +36,7 @@
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
+import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
@@ -74,6 +76,11 @@
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseNovaErrorFromHttpResponse.class);
}
+ @Override
+ protected void bindRetryHandlers() {
+ bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
+ }
+
@Provides
@Singleton
@ServerManagement
diff --git a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java
index f952646..47d8444 100644
--- a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java
+++ b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java
@@ -78,7 +78,7 @@
createServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"server\":{\"name\":\"ralphie\",\"imageRef\":\"2\",\"flavorRef\":\"1\"}}",
"application/json", false);
@@ -98,7 +98,7 @@
HttpRequest request = processor
.createRequest(method, "ralphie", 2, 1, withFile("/etc/jclouds", "foo".getBytes()));
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(
request,
@@ -120,7 +120,7 @@
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1,
withMetadata(ImmutableMap.of("foo", "bar")));
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request,
"{\"server\":{\"name\":\"ralphie\",\"imageRef\":\"2\",\"flavorRef\":\"1\",\"metadata\":{\"foo\":\"bar\"}}}",
@@ -138,7 +138,7 @@
Method method = NovaAsyncClient.class.getMethod("deleteImage", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "DELETE http://endpoint/vapiversion/images/2 HTTP/1.1");
+ assertRequestLineEquals(request, "DELETE http://endpoint/vapi-version/images/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, null, null, false);
@@ -153,7 +153,7 @@
Method method = NovaAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -171,7 +171,7 @@
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
- "GET http://endpoint/vapiversion/servers?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
+ "GET http://endpoint/vapi-version/servers?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -186,7 +186,7 @@
Method method = NovaAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/detail?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -201,7 +201,7 @@
Method method = NovaAsyncClient.class.getMethod("getServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/2?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -216,7 +216,7 @@
Method method = NovaAsyncClient.class.getMethod("getServer", String.class);
HttpRequest request = processor.createRequest(method, "dfdcd0a6-0a2f-11e1-8505-2837371c69ae");
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/dfdcd0a6-0a2f-11e1-8505-2837371c69ae?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/dfdcd0a6-0a2f-11e1-8505-2837371c69ae?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -231,7 +231,7 @@
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/flavors?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/flavors?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -247,7 +247,7 @@
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
- "GET http://endpoint/vapiversion/flavors?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
+ "GET http://endpoint/vapi-version/flavors?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -262,7 +262,7 @@
Method method = NovaAsyncClient.class.getMethod("listFlavors", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/flavors/detail?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/flavors/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -278,7 +278,7 @@
HttpRequest request = processor.createRequest(method, withDetails().changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
- "GET http://endpoint/vapiversion/flavors/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
+ "GET http://endpoint/vapi-version/flavors/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -293,7 +293,7 @@
Method method = NovaAsyncClient.class.getMethod("getFlavor", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/flavors/2?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/flavors/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -308,7 +308,7 @@
Method method = NovaAsyncClient.class.getMethod("getFlavor", String.class);
HttpRequest request = processor.createRequest(method, "209904b6-0a30-11e1-a0f0-2837371c69ae");
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/flavors/209904b6-0a30-11e1-a0f0-2837371c69ae?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/flavors/209904b6-0a30-11e1-a0f0-2837371c69ae?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -323,7 +323,7 @@
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/images?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/images?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -338,7 +338,7 @@
Method method = NovaAsyncClient.class.getMethod("listImages", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, withDetails());
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/images/detail?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/images/detail?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -354,7 +354,7 @@
HttpRequest request = processor.createRequest(method, changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
- "GET http://endpoint/vapiversion/images?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
+ "GET http://endpoint/vapi-version/images?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -370,7 +370,7 @@
HttpRequest request = processor.createRequest(method, withDetails().changesSince(now).maxResults(1).startAt(2));
assertRequestLineEquals(request,
- "GET http://endpoint/vapiversion/images/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
+ "GET http://endpoint/vapi-version/images/detail?format=json&changes-since=10000&limit=1&offset=2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -385,7 +385,7 @@
Method method = NovaAsyncClient.class.getMethod("getImage", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/images/2?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/images/2?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -400,7 +400,7 @@
Method method = NovaAsyncClient.class.getMethod("getImage", int.class);
HttpRequest request = processor.createRequest(method, "3bd52d90-0a30-11e1-83f5-2837371c69ae");
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/images/3bd52d90-0a30-11e1-83f5-2837371c69ae?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/images/3bd52d90-0a30-11e1-83f5-2837371c69ae?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -415,7 +415,7 @@
Method method = NovaAsyncClient.class.getMethod("deleteServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "DELETE http://endpoint/vapiversion/servers/2 HTTP/1.1");
+ assertRequestLineEquals(request, "DELETE http://endpoint/vapi-version/servers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, null, null, false);
@@ -430,7 +430,7 @@
Method method = NovaAsyncClient.class.getMethod("deleteServer", String.class);
HttpRequest request = processor.createRequest(method, "db8a1ac6-0a35-11e1-a42f-2837371c69ae");
- assertRequestLineEquals(request, "DELETE http://endpoint/vapiversion/servers/db8a1ac6-0a35-11e1-a42f-2837371c69ae HTTP/1.1");
+ assertRequestLineEquals(request, "DELETE http://endpoint/vapi-version/servers/db8a1ac6-0a35-11e1-a42f-2837371c69ae HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, null, null, false);
@@ -445,7 +445,7 @@
Method method = NovaAsyncClient.class.getMethod("changeAdminPass", int.class, String.class);
HttpRequest request = processor.createRequest(method, 2, "foo");
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/2/action HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/2/action HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"changePassword\":{\"adminPass\":\"foo\"}}", MediaType.APPLICATION_JSON, false);
@@ -461,7 +461,7 @@
Method method = NovaAsyncClient.class.getMethod("renameServer", int.class, String.class);
HttpRequest request = processor.createRequest(method, 2, "foo");
- assertRequestLineEquals(request, "PUT http://endpoint/vapiversion/servers/2 HTTP/1.1");
+ assertRequestLineEquals(request, "PUT http://endpoint/vapi-version/servers/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"server\":{\"name\":\"foo\"}}", MediaType.APPLICATION_JSON, false);
@@ -477,7 +477,7 @@
Method method = NovaAsyncClient.class.getMethod("getAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/2/ips?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/2/ips?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -492,7 +492,7 @@
Method method = NovaAsyncClient.class.getMethod("listPublicAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/2/ips/public?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/2/ips/public?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -508,7 +508,7 @@
Method method = NovaAsyncClient.class.getMethod("listPrivateAddresses", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "GET http://endpoint/vapiversion/servers/2/ips/private?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "GET http://endpoint/vapi-version/servers/2/ips/private?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
@@ -524,7 +524,7 @@
Method method = NovaAsyncClient.class.getMethod("createImageFromServer", String.class, int.class);
HttpRequest request = processor.createRequest(method, "ralphie", 2);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/images?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/images?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, "{\"image\":{\"serverId\":2,\"name\":\"ralphie\"}}", MediaType.APPLICATION_JSON,
false);
@@ -546,7 +546,7 @@
rebuildServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, 3);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/3/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/3/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"rebuild\":{}}", MediaType.APPLICATION_JSON, false);
@@ -563,7 +563,7 @@
rebuildServerOptionsVarargsClass);
HttpRequest request = processor.createRequest(method, 3, withImage("2"));
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/3/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/3/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"rebuild\":{\"imageRef\":\"2\"}}", MediaType.APPLICATION_JSON, false);
@@ -579,7 +579,7 @@
Method method = NovaAsyncClient.class.getMethod("rebootServer", int.class, RebootType.class);
HttpRequest request = processor.createRequest(method, 2, RebootType.HARD);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/2/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"reboot\":{\"type\":\"HARD\"}}", MediaType.APPLICATION_JSON, false);
@@ -595,7 +595,7 @@
Method method = NovaAsyncClient.class.getMethod("resizeServer", int.class, int.class);
HttpRequest request = processor.createRequest(method, 2, 3);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/2/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"resize\":{\"flavorId\":3}}", MediaType.APPLICATION_JSON, false);
@@ -611,7 +611,7 @@
Method method = NovaAsyncClient.class.getMethod("confirmResizeServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/2/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"confirmResize\":null}", MediaType.APPLICATION_JSON, false);
@@ -626,7 +626,7 @@
Method method = NovaAsyncClient.class.getMethod("revertResizeServer", int.class);
HttpRequest request = processor.createRequest(method, 2);
- assertRequestLineEquals(request, "POST http://endpoint/vapiversion/servers/2/action?format=json HTTP/1.1");
+ assertRequestLineEquals(request, "POST http://endpoint/vapi-version/servers/2/action?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: */*\n");
assertPayloadEquals(request, "{\"revertResize\":null}", MediaType.APPLICATION_JSON, false);
@@ -665,7 +665,7 @@
@Override
protected URI provideServerUrl(AuthenticationResponse response) {
- return URI.create("http://endpoint/vapiversion");
+ return URI.create("http://endpoint/vapi-version");
}
}
@@ -680,7 +680,7 @@
@Override
protected Properties getProperties() {
Properties overrides = new Properties();
- overrides.setProperty(PROPERTY_API_VERSION, "apiversion");
+ overrides.setProperty(PROPERTY_API_VERSION, "api-version");
overrides.setProperty(provider + ".endpoint", "http://endpoint");
overrides.setProperty(provider + ".contextbuilder", NovaContextBuilder.class.getName());
return overrides;
diff --git a/apis/s3/pom.xml b/apis/s3/pom.xml
index 59af2a8..0dd8533 100644
--- a/apis/s3/pom.xml
+++ b/apis/s3/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.s3.blobstore.integration.S3TestInitializer</test.initializer>
<test.s3.endpoint>https://s3.amazonaws.com</test.s3.endpoint>
- <test.s3.apiversion>2006-03-01</test.s3.apiversion>
+ <test.s3.api-version>2006-03-01</test.s3.api-version>
+ <test.s3.build-version></test.s3.build-version>
<test.s3.identity>${test.aws.identity}</test.s3.identity>
<test.s3.credential>${test.aws.credential}</test.s3.credential>
</properties>
@@ -108,7 +109,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.s3.endpoint>${test.s3.endpoint}</test.s3.endpoint>
- <test.s3.apiversion>${test.s3.apiversion}</test.s3.apiversion>
+ <test.s3.api-version>${test.s3.api-version}</test.s3.api-version>
+ <test.s3.build-version>${test.s3.build-version}</test.s3.build-version>
<test.s3.identity>${test.s3.identity}</test.s3.identity>
<test.s3.credential>${test.s3.credential}</test.s3.credential>
</systemPropertyVariables>
diff --git a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java b/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java
index 5265f41..5b784c9 100644
--- a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java
+++ b/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java
@@ -21,7 +21,6 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import org.jclouds.javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -30,10 +29,12 @@
import org.jclouds.date.DateService;
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
+import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RequestSigner;
@@ -42,6 +43,7 @@
import org.jclouds.s3.S3Client;
import org.jclouds.s3.filters.RequestAuthorizeSignature;
import org.jclouds.s3.handlers.ParseS3ErrorFromXmlContent;
+import org.jclouds.s3.handlers.S3RedirectionRetryHandler;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -100,6 +102,11 @@
protected RequestSigner provideRequestSigner(RequestAuthorizeSignature in) {
return in;
}
+
+ @Override
+ protected void bindRetryHandlers() {
+ bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(S3RedirectionRetryHandler.class);
+ }
@Provides
@TimeStamp
diff --git a/common/aws/src/main/java/org/jclouds/aws/handlers/AWSRedirectionRetryHandler.java b/apis/s3/src/main/java/org/jclouds/s3/handlers/S3RedirectionRetryHandler.java
similarity index 90%
rename from common/aws/src/main/java/org/jclouds/aws/handlers/AWSRedirectionRetryHandler.java
rename to apis/s3/src/main/java/org/jclouds/s3/handlers/S3RedirectionRetryHandler.java
index 588c1e6..8871215 100644
--- a/common/aws/src/main/java/org/jclouds/aws/handlers/AWSRedirectionRetryHandler.java
+++ b/apis/s3/src/main/java/org/jclouds/s3/handlers/S3RedirectionRetryHandler.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.jclouds.aws.handlers;
+package org.jclouds.s3.handlers;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
@@ -40,11 +40,11 @@
* @author Adrian Cole
*/
@Singleton
-public class AWSRedirectionRetryHandler extends RedirectionRetryHandler {
+public class S3RedirectionRetryHandler extends RedirectionRetryHandler {
private final AWSUtils utils;
@Inject
- public AWSRedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider,
+ public S3RedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider,
BackoffLimitedRetryHandler backoffHandler, AWSUtils utils) {
super(uriBuilderProvider, backoffHandler);
this.utils = utils;
@@ -54,7 +54,8 @@
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
if (response.getFirstHeaderOrNull(HttpHeaders.LOCATION) == null
&& (response.getStatusCode() == 301 || response.getStatusCode() == 307)) {
- if (command.getCurrentRequest().getMethod() == HttpMethod.HEAD) {
+ if (command.getCurrentRequest().getMethod().equals(HttpMethod.HEAD)) {
+ command.incrementRedirectCount();
command.setCurrentRequest(command.getCurrentRequest().toBuilder().method("GET").build());
return true;
} else {
diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java
index 4c4676f..94b088c 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java
@@ -54,6 +54,7 @@
import org.jclouds.s3.functions.ParseObjectMetadataFromHeaders;
import org.jclouds.s3.functions.ReturnFalseIfBucketAlreadyOwnedByYouOrIllegalState;
import org.jclouds.s3.functions.ReturnTrueOn404OrNotFoundFalseOnIllegalState;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.jclouds.s3.options.CopyObjectOptions;
import org.jclouds.s3.options.ListBucketOptions;
import org.jclouds.s3.options.PutBucketOptions;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientExpectTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3ClientExpectTest.java
new file mode 100644
index 0000000..4fb0c87
--- /dev/null
+++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientExpectTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.s3;
+
+import java.net.URI;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.s3.internal.BaseS3ClientExpectTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "S3ClientExpectTest")
+public class S3ClientExpectTest extends BaseS3ClientExpectTest {
+
+ public void bucketExistsReturnsTrueOn200AndFalseOn404() {
+
+ HttpRequest bucketFooExists = HttpRequest.builder().method("HEAD").endpoint(
+ URI.create("https://foo.s3.amazonaws.com/?max-keys=0")).headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("Host", "foo.s3.amazonaws.com")
+ .put("Date", CONSTANT_DATE)
+ .put("Authorization", "AWS identity:86P4BBb7xT+gBqq7jxM8Tc28ktY=")
+ .build()).build();
+
+ S3Client clientWhenBucketExists = requestSendsResponse(bucketFooExists, HttpResponse.builder().statusCode(200).build());
+ assert clientWhenBucketExists.bucketExists("foo");
+
+ S3Client clientWhenBucketDoesntExist = requestSendsResponse(bucketFooExists, HttpResponse.builder().statusCode(404).build());
+ assert !clientWhenBucketDoesntExist.bucketExists("foo");
+
+ }
+
+}
\ No newline at end of file
diff --git a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredNoPathTest.java b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredNoPathTest.java
index 960ca8e..b4daa5c 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredNoPathTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredNoPathTest.java
@@ -26,8 +26,8 @@
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java
index 0d2c856..a71b488 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java
@@ -29,8 +29,8 @@
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/binders/BindNoBucketLoggingToXmlPayloadTest.java b/apis/s3/src/test/java/org/jclouds/s3/binders/BindNoBucketLoggingToXmlPayloadTest.java
index 0947c06..8193552 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/binders/BindNoBucketLoggingToXmlPayloadTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/binders/BindNoBucketLoggingToXmlPayloadTest.java
@@ -25,8 +25,8 @@
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequestTest.java b/apis/s3/src/test/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequestTest.java
index 4d9664f..34d4b5f 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequestTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/binders/BindS3ObjectMetadataToRequestTest.java
@@ -30,9 +30,9 @@
import org.jclouds.io.Payload;
import org.jclouds.io.Payloads;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
import org.jclouds.s3.domain.S3Object;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java b/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java
index 30c6998..c88a778 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java
@@ -32,10 +32,10 @@
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
import org.jclouds.s3.S3Client;
import org.jclouds.s3.config.S3RestClientModule;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/blobstore/integration/S3TestInitializer.java b/apis/s3/src/test/java/org/jclouds/s3/blobstore/integration/S3TestInitializer.java
index 54a0660..4598042 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/blobstore/integration/S3TestInitializer.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/blobstore/integration/S3TestInitializer.java
@@ -41,10 +41,10 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
+ new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
}
}
diff --git a/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java b/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java
index d23d61f..4be1ded 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java
@@ -29,11 +29,11 @@
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
import org.jclouds.s3.domain.AccessControlList;
import org.jclouds.s3.domain.CannedAccessPolicy;
import org.jclouds.s3.domain.S3Object;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.jclouds.s3.options.PutObjectOptions;
import org.jclouds.s3.reference.S3Headers;
import org.testng.annotations.DataProvider;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/handlers/S3RedirectionRetryHandlerExpectTest.java b/apis/s3/src/test/java/org/jclouds/s3/handlers/S3RedirectionRetryHandlerExpectTest.java
new file mode 100644
index 0000000..eae7e10
--- /dev/null
+++ b/apis/s3/src/test/java/org/jclouds/s3/handlers/S3RedirectionRetryHandlerExpectTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.s3.handlers;
+
+import java.net.URI;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.s3.S3Client;
+import org.jclouds.s3.internal.BaseS3ClientExpectTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "S3RedirectionRetryHandlerExpectTest")
+public class S3RedirectionRetryHandlerExpectTest extends BaseS3ClientExpectTest {
+
+ public void testRedirectOnHeadBucketChangesRequestToGetBucket() {
+
+ HttpRequest bucketFooExists = HttpRequest.builder().method("HEAD").endpoint(
+ URI.create("https://foo.s3.amazonaws.com/?max-keys=0")).headers(
+ ImmutableMultimap.<String, String> builder().put("Host", "foo.s3.amazonaws.com").put("Date",
+ CONSTANT_DATE).put("Authorization", "AWS identity:86P4BBb7xT+gBqq7jxM8Tc28ktY=").build())
+ .build();
+
+ HttpResponse redirectResponse = HttpResponse.builder().statusCode(301).build();
+
+ HttpRequest bucketFooExistsNowUsesGET = HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://foo.s3.amazonaws.com/?max-keys=0")).headers(
+ ImmutableMultimap.<String, String> builder().put("Host", "foo.s3.amazonaws.com").put("Date",
+ CONSTANT_DATE).put("Authorization", "AWS identity:ZWVz2v/jGB+ZMmijoyfH9mFMPo0=").build())
+ .build();
+
+ HttpResponse success = HttpResponse.builder().statusCode(200).build();
+
+ S3Client clientWhenBucketExists = requestsSendResponses(bucketFooExists, redirectResponse, bucketFooExistsNowUsesGET, success);
+
+ assert clientWhenBucketExists.bucketExists("foo");
+
+ }
+}
\ No newline at end of file
diff --git a/apis/s3/src/test/java/org/jclouds/s3/BaseS3AsyncClientTest.java b/apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3AsyncClientTest.java
similarity index 94%
rename from apis/s3/src/test/java/org/jclouds/s3/BaseS3AsyncClientTest.java
rename to apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3AsyncClientTest.java
index 2cfa94d..f161cf8 100644
--- a/apis/s3/src/test/java/org/jclouds/s3/BaseS3AsyncClientTest.java
+++ b/apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3AsyncClientTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.jclouds.s3;
+package org.jclouds.s3.internal;
import static org.testng.Assert.assertEquals;
@@ -27,6 +27,9 @@
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
+import org.jclouds.s3.S3AsyncClient;
+import org.jclouds.s3.S3ContextBuilder;
+import org.jclouds.s3.S3PropertiesBuilder;
import org.jclouds.s3.blobstore.functions.BlobToObject;
import org.jclouds.s3.filters.RequestAuthorizeSignature;
import org.testng.annotations.BeforeClass;
diff --git a/apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3ClientExpectTest.java b/apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3ClientExpectTest.java
new file mode 100644
index 0000000..57318b5
--- /dev/null
+++ b/apis/s3/src/test/java/org/jclouds/s3/internal/BaseS3ClientExpectTest.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.s3.internal;
+
+import java.util.Properties;
+
+import org.jclouds.date.TimeStamp;
+import org.jclouds.http.RequiresHttp;
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.jclouds.rest.ConfiguresRestClient;
+import org.jclouds.s3.S3AsyncClient;
+import org.jclouds.s3.S3Client;
+import org.jclouds.s3.S3ContextBuilder;
+import org.jclouds.s3.S3PropertiesBuilder;
+import org.jclouds.s3.config.S3RestClientModule;
+
+import com.google.common.base.Supplier;
+import com.google.inject.Module;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+public abstract class BaseS3ClientExpectTest extends BaseRestClientExpectTest<S3Client> {
+
+ protected static final String CONSTANT_DATE = "2009-11-08T15:54:08.897Z";
+
+ public BaseS3ClientExpectTest() {
+ provider = "s3";
+ }
+
+ @Override
+ protected Properties setupRestProperties() {
+ Properties overrides = new Properties();
+ overrides.setProperty(provider + ".endpoint", "https://s3.amazonaws.com");
+ overrides.setProperty(provider + ".propertiesbuilder", S3PropertiesBuilder.class.getName());
+ overrides.setProperty(provider + ".contextbuilder", S3ContextBuilder.class.getName());
+ return overrides;
+ }
+
+ @RequiresHttp
+ @ConfiguresRestClient
+ private static final class TestS3RestClientModule extends S3RestClientModule<S3Client, S3AsyncClient> {
+
+ public TestS3RestClientModule() {
+ super(S3Client.class, S3AsyncClient.class);
+ }
+
+ @Override
+ protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
+ return CONSTANT_DATE;
+ }
+ }
+
+ @Override
+ protected Module createModule() {
+ return new TestS3RestClientModule();
+ }
+}
\ No newline at end of file
diff --git a/apis/swift/pom.xml b/apis/swift/pom.xml
index 3290e70..a998434 100644
--- a/apis/swift/pom.xml
+++ b/apis/swift/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer</test.initializer>
<test.swift.endpoint>http://localhost:11000</test.swift.endpoint>
- <test.swift.apiversion>1.0</test.swift.apiversion>
+ <test.swift.api-version>1.0</test.swift.api-version>
+ <test.swift.build-version></test.swift.build-version>
<test.swift.identity>test:tester</test.swift.identity>
<test.swift.credential>testing</test.swift.credential>
</properties>
@@ -108,7 +109,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.swift.endpoint>${test.swift.endpoint}</test.swift.endpoint>
- <test.swift.apiversion>${test.swift.apiversion}</test.swift.apiversion>
+ <test.swift.api-version>${test.swift.api-version}</test.swift.api-version>
+ <test.swift.build-version>${test.swift.build-version}</test.swift.build-version>
<test.swift.identity>${test.swift.identity}</test.swift.identity>
<test.swift.credential>${test.swift.credential}</test.swift.credential>
</systemPropertyVariables>
diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/config/BaseSwiftRestClientModule.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/config/BaseSwiftRestClientModule.java
index fe311a6..b0a1445 100644
--- a/apis/swift/src/main/java/org/jclouds/openstack/swift/config/BaseSwiftRestClientModule.java
+++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/config/BaseSwiftRestClientModule.java
@@ -23,6 +23,7 @@
import javax.inject.Singleton;
import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@@ -31,6 +32,7 @@
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
+import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
import org.jclouds.openstack.swift.CommonSwiftClient;
@@ -76,6 +78,11 @@
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseSwiftErrorFromHttpResponse.class);
}
+ @Override
+ protected void bindRetryHandlers() {
+ bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
+ }
+
@Provides
@Singleton
@Storage
diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftTestInitializer.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftTestInitializer.java
index 56b1783..6f51336 100644
--- a/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftTestInitializer.java
+++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/blobstore/integration/SwiftTestInitializer.java
@@ -39,10 +39,10 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
+ new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
}
}
diff --git a/apis/vcloud/pom.xml b/apis/vcloud/pom.xml
index 744278b..d7a50e9 100644
--- a/apis/vcloud/pom.xml
+++ b/apis/vcloud/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.vcloud.endpoint>FIXME</test.vcloud.endpoint>
- <test.vcloud.apiversion>1.0</test.vcloud.apiversion>
+ <test.vcloud.api-version>1.0</test.vcloud.api-version>
+ <test.vcloud.build-version></test.vcloud.build-version>
<test.vcloud.identity>FIXME</test.vcloud.identity>
<test.vcloud.credential>FIXME</test.vcloud.credential>
<test.vcloud.image-id />
@@ -105,7 +106,8 @@
<configuration>
<systemPropertyVariables>
<test.vcloud.endpoint>${test.vcloud.endpoint}</test.vcloud.endpoint>
- <test.vcloud.apiversion>${test.vcloud.apiversion}</test.vcloud.apiversion>
+ <test.vcloud.api-version>${test.vcloud.api-version}</test.vcloud.api-version>
+ <test.vcloud.build-version>${test.vcloud.build-version}</test.vcloud.build-version>
<test.vcloud.identity>${test.vcloud.identity}</test.vcloud.identity>
<test.vcloud.credential>${test.vcloud.credential}</test.vcloud.credential>
<test.vcloud.image-id>${test.vcloud.image-id}</test.vcloud.image-id>
diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/IsDefaultVDC.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/IsDefaultVDC.java
index f534314..29a3e7b 100644
--- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/IsDefaultVDC.java
+++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/IsDefaultVDC.java
@@ -1,12 +1,8 @@
/**
- *
- * Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
- *
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
+ * 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. The ASF licenses this file
+ * 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
@@ -19,7 +15,6 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- * ====================================================================
*/
package org.jclouds.vcloud.compute.config;
diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java
index 5b58c08..276261c 100644
--- a/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java
+++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java
@@ -81,7 +81,7 @@
@Override
public RestContextSpec<VCloudVersionsClient, VCloudVersionsAsyncClient> createContextSpec() {
- return contextSpec("test", "http://localhost:8080", "1", "", "identity", "credential",
+ return contextSpec("test", "http://localhost:8080", "1", "", "", "identity", "credential",
VCloudVersionsClient.class, VCloudVersionsAsyncClient.class);
}
diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/VCloudLoginAsyncClientTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/VCloudLoginAsyncClientTest.java
index 87bb807..3cec095 100644
--- a/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/VCloudLoginAsyncClientTest.java
+++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/internal/VCloudLoginAsyncClientTest.java
@@ -107,7 +107,7 @@
@Override
public RestContextSpec<VCloudLoginClient, VCloudLoginAsyncClient> createContextSpec() {
- return contextSpec("test", "http://localhost:8080/login", "1", "", "identity", "credential",
+ return contextSpec("test", "http://localhost:8080/login", "1", "", "", "identity", "credential",
VCloudLoginClient.class, VCloudLoginAsyncClient.class);
}
}
diff --git a/apis/walrus/pom.xml b/apis/walrus/pom.xml
index 5080196..0febe97 100644
--- a/apis/walrus/pom.xml
+++ b/apis/walrus/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.walrus.blobstore.WalrusTestInitializer</test.initializer>
<test.walrus.endpoint>http://ecc.eucalyptus.com:8773/services/Walrus</test.walrus.endpoint>
- <test.walrus.apiversion>2006-03-01</test.walrus.apiversion>
+ <test.walrus.api-version>2006-03-01</test.walrus.api-version>
+ <test.walrus.build-version></test.walrus.build-version>
<test.walrus.identity>${test.eucalyptus.identity}</test.walrus.identity>
<test.walrus.credential>${test.eucalyptus.credential}</test.walrus.credential>
</properties>
@@ -104,7 +105,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.walrus.endpoint>${test.walrus.endpoint}</test.walrus.endpoint>
- <test.walrus.apiversion>${test.walrus.apiversion}</test.walrus.apiversion>
+ <test.walrus.api-version>${test.walrus.api-version}</test.walrus.api-version>
+ <test.walrus.build-version>${test.walrus.build-version}</test.walrus.build-version>
<test.walrus.identity>${test.walrus.identity}</test.walrus.identity>
<test.walrus.credential>${test.walrus.credential}</test.walrus.credential>
</systemPropertyVariables>
diff --git a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml
index ea96693..41cd0de 100644
--- a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml
@@ -58,7 +58,8 @@
<properties>
<test.${lcaseProviderName}.identity>${providerIdentity}</test.${lcaseProviderName}.identity>
<test.${lcaseProviderName}.credential>${providerCredential}</test.${lcaseProviderName}.credential>
- <test.${lcaseProviderName}.apiversion>${providerApiVersion}</test.${lcaseProviderName}.apiversion>
+ <test.${lcaseProviderName}.api-version>${providerApiVersion}</test.${lcaseProviderName}.api-version>
+ <test.${lcaseProviderName}.build-version></test.${lcaseProviderName}.build-version>
<test.${lcaseProviderName}.endpoint>${providerEndpoint}</test.${lcaseProviderName}.endpoint>
</properties>
<dependencies>
@@ -107,7 +108,8 @@
<test.${lcaseProviderName}.identity>\$\{test.${lcaseProviderName}.identity\}</test.${lcaseProviderName}.identity>
<test.${lcaseProviderName}.credential>\$\{test.${lcaseProviderName}.credential\}</test.${lcaseProviderName}.credential>
<test.${lcaseProviderName}.endpoint>\$\{test.${lcaseProviderName}.endpoint\}</test.${lcaseProviderName}.endpoint>
- <test.${lcaseProviderName}.apiversion>\$\{test.${lcaseProviderName}.apiversion\}</test.${lcaseProviderName}.apiversion>
+ <test.${lcaseProviderName}.api-version>\$\{test.${lcaseProviderName}.api-version\}</test.${lcaseProviderName}.api-version>
+ <test.${lcaseProviderName}.build-version>\$\{test.${lcaseProviderName}.build-version\}</test.${lcaseProviderName}.build-version>
</systemPropertyVariables>
</configuration>
</execution>
diff --git a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ClientLiveTest.java b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ClientLiveTest.java
index 3938b3a..df5b054 100644
--- a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ClientLiveTest.java
+++ b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ClientLiveTest.java
@@ -55,7 +55,7 @@
identity = checkNotNull(System.getProperty("test.${lcaseProviderName}.identity"), "test.${lcaseProviderName}.identity");
credential = checkNotNull(System.getProperty("test.${lcaseProviderName}.credential"), "test.${lcaseProviderName}.credential");
endpoint = checkNotNull(System.getProperty("test.${lcaseProviderName}.endpoint"), "test.${lcaseProviderName}.endpoint");
- apiVersion = checkNotNull(System.getProperty("test.${lcaseProviderName}.apiversion"), "test.${lcaseProviderName}.apiversion");
+ apiVersion = checkNotNull(System.getProperty("test.${lcaseProviderName}.api-version"), "test.${lcaseProviderName}.api-version");
}
@BeforeGroups(groups = { "live" })
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobStores.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobStores.java
index 1aac1a0..fb3b418 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/BlobStores.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobStores.java
@@ -1,3 +1,21 @@
+/**
+ * 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.blobstore;
import java.util.Iterator;
diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java
index 750db0d..31dd22d 100644
--- a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java
+++ b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java
@@ -21,8 +21,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import javax.inject.Singleton;
-
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobRequestSigner;
import org.jclouds.blobstore.BlobStore;
@@ -36,7 +34,6 @@
import org.jclouds.location.config.JustProviderLocationModule;
import com.google.inject.AbstractModule;
-import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
@@ -63,13 +60,9 @@
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
install(new JustProviderLocationModule());
+ bind(BlobStore.class).to(TransientBlobStore.class);
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);
}
- @Provides
- @Singleton
- BlobStore provide(TransientBlobStore in) {
- return in;
- }
}
diff --git a/blobstore/src/test/java/org/jclouds/blobstore/BlobStoresTest.java b/blobstore/src/test/java/org/jclouds/blobstore/BlobStoresTest.java
index 42e35b9..9ea6d13 100644
--- a/blobstore/src/test/java/org/jclouds/blobstore/BlobStoresTest.java
+++ b/blobstore/src/test/java/org/jclouds/blobstore/BlobStoresTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.blobstore;
import static org.easymock.classextension.EasyMock.createMock;
diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobStoreTestInitializer.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobStoreTestInitializer.java
index 10095cb..201287f 100644
--- a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobStoreTestInitializer.java
+++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientBlobStoreTestInitializer.java
@@ -32,10 +32,10 @@
public class TransientBlobStoreTestInitializer extends BaseTestInitializer {
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String url, String apiversion, String app,
+ protected BlobStoreContext createLiveContext(Module configurationModule, String url, String apiVersion,String buildVersion, String app,
String identity, String key) throws IOException {
return createStubContext();
}
-}
\ No newline at end of file
+}
diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseTestInitializer.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseTestInitializer.java
index 02c8031..ecfb416 100644
--- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseTestInitializer.java
+++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseTestInitializer.java
@@ -37,7 +37,8 @@
String app = System.getProperty("test.app");
String identity = System.getProperty("test." + provider + ".identity");
String credential = System.getProperty("test." + provider + ".credential");
- String apiversion = System.getProperty("test." + provider + ".apiversion");
+ String apiVersion = System.getProperty("test." + provider + ".api-version");
+ String buildVersion = System.getProperty("test." + provider + ".build-version");
if (endpoint != null)
testContext.setAttribute("test." + provider + ".endpoint", endpoint);
if (app != null)
@@ -46,16 +47,27 @@
testContext.setAttribute("test." + provider + ".identity", identity);
if (credential != null)
testContext.setAttribute("test." + provider + ".credential", credential);
- if (credential != null)
- testContext.setAttribute("test." + provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ testContext.setAttribute("test." + provider + ".api-version", apiVersion);
+ if (buildVersion != null)
+ testContext.setAttribute("test." + provider + ".build-version", buildVersion);
if (identity != null) {
- return createLiveContext(configurationModule, endpoint, apiversion, app, identity, credential);
+ return createLiveContext(configurationModule, endpoint, apiVersion, buildVersion, app, identity, credential);
} else {
return createStubContext();
}
}
+
- protected Properties setupProperties(String endpoint, String apiversion, String identity, String credential) {
+ /**
+ * To be removed in jclouds 1.4
+ */
+ @Deprecated
+ protected Properties setupProperties(String endpoint, String apiVersion, String identity, String credential) {
+ return setupProperties(endpoint, apiVersion, "", identity, credential);
+ }
+
+ protected Properties setupProperties(String endpoint, String apiVersion, String buildVersion, String identity, String credential) {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
@@ -65,8 +77,10 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (buildVersion != null)
+ overrides.setProperty(provider + ".build-version", buildVersion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
@@ -74,6 +88,6 @@
return new BlobStoreContextFactory().createContext("transient", "foo", "bar");
}
- protected abstract BlobStoreContext createLiveContext(Module configurationModule, String url, String apiversion,
- String app, String identity, String key) throws IOException;
-}
\ No newline at end of file
+ protected abstract BlobStoreContext createLiveContext(Module configurationModule, String url, String apiVersion,
+ String buildVersion, String app, String identity, String key) throws IOException;
+}
diff --git a/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java b/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java
index 2d7cc33..b4440ef 100644
--- a/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java
+++ b/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java
@@ -24,11 +24,9 @@
import java.util.Map;
import java.util.Set;
-import org.jclouds.javax.annotation.Nullable;
import javax.inject.Singleton;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
-import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
@@ -36,6 +34,7 @@
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
+import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import org.jclouds.location.config.ProvideRegionToURIViaProperties;
@@ -73,7 +72,6 @@
@Override
protected void bindRetryHandlers() {
- bind(HttpRetryHandler.class).annotatedWith(Redirection.class).to(AWSRedirectionRetryHandler.class);
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class);
}
diff --git a/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java b/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java
index e475aaf..12321d8 100644
--- a/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java
+++ b/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java
@@ -17,15 +17,13 @@
* under the License.
*/
package org.jclouds.aws.filters;
-
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.testng.Assert.assertEquals;
-import java.util.List;
-import java.util.Map;
-
import org.jclouds.PropertiesBuilder;
import org.jclouds.date.TimeStamp;
+import org.jclouds.http.IntegrationTestAsyncClient;
+import org.jclouds.http.IntegrationTestClient;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.RequestSigner;
import org.jclouds.rest.RestContextBuilder;
@@ -49,8 +47,9 @@
@Test(groups = "unit", testName = "FormSignerTest")
public class FormSignerTest {
@SuppressWarnings("unchecked")
- public static final RestContextSpec<Map, List> DUMMY_SPEC = new RestContextSpec<Map, List>("provider", "endpoint",
- "apiVersion", "", "identity", "credential", Map.class, List.class, PropertiesBuilder.class,
+ public static final RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> DUMMY_SPEC = new RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient>(
+ "provider", "endpoint", "apiVersion", "buildVersion", "", "identity", "credential",
+ IntegrationTestClient.class, IntegrationTestAsyncClient.class, PropertiesBuilder.class,
(Class) RestContextBuilder.class, ImmutableList.<Module> of(new MockModule(), new NullLoggingModule(),
new AbstractModule() {
@Override
diff --git a/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java b/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
index 690c8ad..d3f1bbd 100644
--- a/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
+++ b/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
@@ -22,8 +22,6 @@
import java.io.IOException;
import java.net.URI;
-import java.util.List;
-import java.util.Map;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.HttpHeaders;
@@ -31,6 +29,8 @@
import org.jclouds.PropertiesBuilder;
import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
import org.jclouds.http.HttpRequest;
+import org.jclouds.http.IntegrationTestAsyncClient;
+import org.jclouds.http.IntegrationTestClient;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.RestContextBuilder;
import org.jclouds.rest.RestContextFactory;
@@ -137,10 +137,11 @@
}
@SuppressWarnings("unchecked")
- public static final RestContextSpec<Map, List> DUMMY_SPEC = new RestContextSpec<Map, List>("provider", "endpoint",
- "apiVersion", "", "identity", "credential", Map.class, List.class, PropertiesBuilder.class,
- (Class) RestContextBuilder.class, ImmutableList.<Module> of(new MockModule(), new NullLoggingModule(),
- new AzureStorageRestClientModule<Exception, RuntimeException>(Exception.class,
- RuntimeException.class)));
+ public static final RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> DUMMY_SPEC = new RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient>(
+ "provider", "endpoint", "apiVersion", "buildVersion", "", "identity", "credential", IntegrationTestClient.class,
+ IntegrationTestAsyncClient.class, PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList
+ .<Module> of(new MockModule(), new NullLoggingModule(),
+ new AzureStorageRestClientModule<IntegrationTestClient, IntegrationTestAsyncClient>(IntegrationTestClient.class,
+ IntegrationTestAsyncClient.class)));
}
\ No newline at end of file
diff --git a/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java b/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java
index f471e12..e7f180d 100644
--- a/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java
+++ b/common/openstack/src/main/java/org/jclouds/openstack/config/OpenStackAuthenticationModule.java
@@ -40,6 +40,10 @@
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.util.concurrent.UncheckedExecutionException;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -104,10 +108,41 @@
@Provides
@Singleton
- Supplier<AuthenticationResponse> provideAuthenticationResponseCache(
+ public LoadingCache<String,AuthenticationResponse> provideAuthenticationResponseCache2(
final GetAuthenticationResponse getAuthenticationResponse) {
- return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<AuthenticationResponse>(
- getAuthenticationResponse), 23, TimeUnit.HOURS);
+
+ final RetryOnTimeOutExceptionSupplier<AuthenticationResponse> delegate =
+ new RetryOnTimeOutExceptionSupplier<AuthenticationResponse>(getAuthenticationResponse);
+
+ CacheLoader<String, AuthenticationResponse> cacheLoader = new CacheLoader<String, AuthenticationResponse>() {
+ @Override
+ public AuthenticationResponse load(String key) throws Exception {
+ return delegate.get();
+ }
+ };
+
+ LoadingCache<String, AuthenticationResponse> cache = CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
+ .build(cacheLoader);
+
+ return cache;
+ }
+
+ @Provides
+ @Singleton
+ protected Supplier<AuthenticationResponse> provideAuthenticationResponseSupplier(
+ final LoadingCache<String,AuthenticationResponse> cache) {
+ return new Supplier<AuthenticationResponse>() {
+ @Override
+ public AuthenticationResponse get() {
+ try {
+ return cache.get("key");
+ } catch (UncheckedExecutionException e) {
+ throw Throwables.propagate(e.getCause());
+ } catch (ExecutionException e) {
+ throw Throwables.propagate(e.getCause());
+ }
+ }
+ };
}
@Provides
diff --git a/common/openstack/src/main/java/org/jclouds/openstack/handlers/RetryOnRenew.java b/common/openstack/src/main/java/org/jclouds/openstack/handlers/RetryOnRenew.java
new file mode 100644
index 0000000..edb39e1
--- /dev/null
+++ b/common/openstack/src/main/java/org/jclouds/openstack/handlers/RetryOnRenew.java
@@ -0,0 +1,98 @@
+/**
+ * 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.handlers;
+
+import static org.jclouds.http.HttpUtils.releasePayload;
+
+import java.io.IOException;
+
+import javax.annotation.Resource;
+
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
+import org.jclouds.openstack.reference.AuthHeaders;
+import org.jclouds.util.Strings2;
+
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Multimap;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * This will parse and set an appropriate exception on the command object.
+ *
+ * @author Adrian Cole
+ *
+ */
+@Singleton
+public class RetryOnRenew implements HttpRetryHandler {
+ @Resource
+ protected Logger logger = Logger.NULL;
+
+ // This doesn't work yet
+// @Inject
+// Supplier<AuthenticationResponse> providedAuthenticationResponseCache;
+
+ @Inject
+ LoadingCache<String,AuthenticationResponse> authenticationResponseCache;
+
+ @Override
+ public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
+ boolean retry = false; // default
+ try {
+ switch (response.getStatusCode()) {
+ case 401:
+ // Do not retry on 401 from authentication request
+ Multimap<String, String> headers = command.getCurrentRequest().getHeaders();
+ if (headers != null && headers.containsKey(AuthHeaders.AUTH_USER) && headers.containsKey(AuthHeaders.AUTH_KEY) &&
+ !headers.containsKey(AuthHeaders.AUTH_TOKEN)) {
+ retry = false;
+ } else {
+ String content = parsePayloadOrNull(response);
+ if (content != null && content.contains("lease renew")) {
+ // Otherwise invalidate the token cache, to force reauthentication
+ authenticationResponseCache.invalidateAll();
+ retry = true;
+ } else {
+ retry = false;
+ }
+ }
+ break;
+ }
+ return retry;
+
+ } finally {
+ releasePayload(response);
+ }
+ }
+
+ String parsePayloadOrNull(HttpResponse response) {
+ if (response.getPayload() != null) {
+ try {
+ return Strings2.toStringAndClose(response.getPayload().getInput());
+ } catch (IOException e) {
+ logger.warn(e, "exception reading error from response", response);
+ }
+ }
+ return null;
+ }
+}
diff --git a/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java b/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java
index 61edf2c..293174f 100644
--- a/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java
+++ b/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java
@@ -76,7 +76,7 @@
@Override
public RestContextSpec<OpenStackAuthClient, OpenStackAuthAsyncClient> createContextSpec() {
- return contextSpec("test", "http://localhost:8080", "1.0", "", "identity", "credential",
+ return contextSpec("test", "http://localhost:8080", "1.0", "", "", "identity", "credential",
OpenStackAuthClient.class, OpenStackAuthAsyncClient.class);
}
diff --git a/common/openstack/src/test/java/org/jclouds/openstack/handlers/RetryOnRenewTest.java b/common/openstack/src/test/java/org/jclouds/openstack/handlers/RetryOnRenewTest.java
new file mode 100644
index 0000000..0aa578f
--- /dev/null
+++ b/common/openstack/src/test/java/org/jclouds/openstack/handlers/RetryOnRenewTest.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.handlers;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.cache.LoadingCache;
+
+/**
+ * Tests behavior of {@code RetryOnRenew} handler
+ *
+ * @author grkvlt@apache.org
+ */
+@Test(groups = "unit", testName = "RetryOnRenewTest")
+public class RetryOnRenewTest {
+ @Test
+ public void test401ShouldRetry() {
+ HttpCommand command = createMock(HttpCommand.class);
+ HttpRequest request = createMock(HttpRequest.class);
+ HttpResponse response = createMock(HttpResponse.class);
+ @SuppressWarnings("unchecked")
+ LoadingCache<String,AuthenticationResponse> cache = createMock(LoadingCache.class);
+
+ expect(command.getCurrentRequest()).andReturn(request);
+
+ cache.invalidateAll();
+ expectLastCall();
+
+ expect(response.getPayload()).andReturn(Payloads.newStringPayload("token expired, please renew")).anyTimes();
+ expect(response.getStatusCode()).andReturn(401).atLeastOnce();
+
+ replay(command);
+ replay(response);
+ replay(cache);
+
+ RetryOnRenew retry = new RetryOnRenew();
+ retry.authenticationResponseCache = cache;
+
+ assertTrue(retry.shouldRetryRequest(command, response));
+
+ verify(command);
+ verify(response);
+ verify(cache);
+ }
+}
diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java
index 441b647..a507ac1 100644
--- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java
+++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java
@@ -34,8 +34,6 @@
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
-import org.jclouds.rest.RestContext;
-import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudAsyncClient;
import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient;
import org.jclouds.trmk.vcloud_0_8.compute.TerremarkVCloudComputeService;
@@ -96,9 +94,6 @@
bind(new TypeLiteral<ComputeServiceContext>() {
}).to(new TypeLiteral<ComputeServiceContextImpl<TerremarkVCloudClient, TerremarkVCloudAsyncClient>>() {
}).in(Scopes.SINGLETON);
- bind(new TypeLiteral<RestContext<TerremarkVCloudClient, TerremarkVCloudAsyncClient>>() {
- }).to(new TypeLiteral<RestContextImpl<TerremarkVCloudClient, TerremarkVCloudAsyncClient>>() {
- }).in(Scopes.SINGLETON);
bind(new TypeLiteral<Function<Org, Iterable<? extends Image>>>() {
}).to(new TypeLiteral<ImagesInVCloudExpressOrg>() {
});
diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java
index 9f75e17..29374b3 100644
--- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java
+++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/compute/suppliers/VAppTemplatesInOrgsLiveTest.java
@@ -18,14 +18,13 @@
*/
package org.jclouds.trmk.vcloud_0_8.compute.suppliers;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.domain.Image;
import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@@ -48,38 +47,17 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class VAppTemplatesInOrgsLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "VAppTemplatesInOrgsLiveTest")
+public class VAppTemplatesInOrgsLiveTest extends BaseVersionedServiceLiveTest {
+ public VAppTemplatesInOrgsLiveTest() {
+ provider = "trmk-vcloudexpress";
+ }
private TerremarkVCloudClient tmClient;
private VAppTemplatesInOrgs parser;
private Closer closer;
private AllCatalogItemsInOrg allCatalogItemsInOrg;
- protected String provider = "trmk-vcloudexpress";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudLoginAsyncClientTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudLoginAsyncClientTest.java
index 7b9df30..f728d20 100644
--- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudLoginAsyncClientTest.java
+++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudLoginAsyncClientTest.java
@@ -108,7 +108,7 @@
@Override
public RestContextSpec<VCloudLoginClient, TerremarkVCloudLoginAsyncClient> createContextSpec() {
- return contextSpec("test", "http://localhost:8080/login", "1", "", "identity", "credential",
+ return contextSpec("test", "http://localhost:8080/login", "1", "", "", "identity", "credential",
VCloudLoginClient.class, TerremarkVCloudLoginAsyncClient.class);
}
}
diff --git a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudVersionsAsyncClientTest.java b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudVersionsAsyncClientTest.java
index 49eeb94..1399a22 100644
--- a/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudVersionsAsyncClientTest.java
+++ b/common/trmk/src/test/java/org/jclouds/trmk/vcloud_0_8/internal/TerremarkVCloudVersionsAsyncClientTest.java
@@ -82,7 +82,7 @@
@Override
public RestContextSpec<VCloudVersionsClient, TerremarkVCloudVersionsAsyncClient> createContextSpec() {
- return contextSpec("test", "http://localhost:8080", "1", "", "identity", "credential",
+ return contextSpec("test", "http://localhost:8080", "1", "", "", "identity", "credential",
VCloudVersionsClient.class, TerremarkVCloudVersionsAsyncClient.class);
}
diff --git a/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java b/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java
index f508c04..b226610 100644
--- a/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java
+++ b/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java
@@ -28,26 +28,26 @@
* @author Adrian Cole
*/
public class StandaloneComputeServiceContextSpec<D, N, H, I, L> extends RestContextSpec<D, D> {
- public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes,
- String identity, String credential, Class<D> driverClass,
+ public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String buildVersion,
+ String iso3166Codes, String identity, String credential, Class<D> driverClass,
Class<? extends StandaloneComputeServiceContextBuilder<D>> contextBuilderClass) {
- this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, contextBuilderClass,
- ImmutableSet.<Module> of());
+ this(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, driverClass,
+ contextBuilderClass, ImmutableSet.<Module> of());
}
- public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes,
- String identity, String credential, Class<D> driverClass,
+ public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String buildVersion,
+ String iso3166Codes, String identity, String credential, Class<D> driverClass,
Class<? extends StandaloneComputeServiceContextBuilder<D>> contextBuilderClass, Iterable<Module> modules) {
- this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, PropertiesBuilder.class,
- contextBuilderClass, modules);
+ this(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, driverClass,
+ PropertiesBuilder.class, contextBuilderClass, modules);
}
@SuppressWarnings( { "unchecked", "rawtypes" })
- public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes,
- String identity, String credential, Class<D> driverClass,
+ public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String buildVersion,
+ String iso3166Codes, String identity, String credential, Class<D> driverClass,
Class<? extends PropertiesBuilder> propertiesBuilderClass,
Class<? extends StandaloneComputeServiceContextBuilder<D>> contextBuilderClass, Iterable<Module> modules) {
- super(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, driverClass,
+ super(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, driverClass, driverClass,
(Class) propertiesBuilderClass, (Class) contextBuilderClass, modules);
}
}
\ No newline at end of file
diff --git a/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java b/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java
index ded9d6d..8ebb352 100644
--- a/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java
+++ b/compute/src/main/java/org/jclouds/compute/callables/BlockUntilInitScriptStatusIsZeroThenReturnOutput.java
@@ -26,7 +26,6 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.jclouds.Constants;
@@ -109,8 +108,7 @@
* Submits a thread that will either set the result of the future or the exception that took
* place
*/
- @PostConstruct
- BlockUntilInitScriptStatusIsZeroThenReturnOutput init() {
+ public BlockUntilInitScriptStatusIsZeroThenReturnOutput init() {
userThreads.submit(new Runnable() {
@Override
public void run() {
diff --git a/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java b/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java
index f05300b..8dbe9cd 100644
--- a/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java
+++ b/compute/src/main/java/org/jclouds/compute/callables/SudoAwareInitManager.java
@@ -21,7 +21,6 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
-import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.inject.Named;
@@ -61,7 +60,6 @@
this.init = checkNotNull(init, "init");
}
- @PostConstruct
public SudoAwareInitManager init() {
ssh = sshFactory.apply(node);
return this;
diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
index 71a8441..1c3cbbc 100644
--- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
+++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java
@@ -81,7 +81,7 @@
@Override
protected void configure() {
- install(new LocationModule(authException));
+ configureLocationModule();
install(new ComputeServiceTimeoutsModule());
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
}).to(CreateSshClientOncePortIsListeningOnNode.class);
@@ -115,6 +115,10 @@
install(new FactoryModuleBuilder().build(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class));
}
+ protected void configureLocationModule() {
+ install(new LocationModule(authException));
+ }
+
@Singleton
static class RunScriptOnNodeFactoryImpl implements RunScriptOnNode.Factory {
@@ -176,7 +180,7 @@
template = provideTemplate(injector, template);
String imageId = config.apply(provider + ".image-id");
if (imageId == null)
- imageId = config.apply("jclouds.image-id");
+ imageId = config.apply(ComputeServiceConstants.PROPERTY_IMAGE_ID);
if (imageId != null)
template.imageId(imageId);
return template;
diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java
index 5c915b3..a225389 100644
--- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java
+++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java
@@ -18,11 +18,15 @@
*/
package org.jclouds.compute.config;
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
import java.util.Set;
import javax.inject.Inject;
+import javax.inject.Named;
import javax.inject.Singleton;
+import org.jclouds.collect.Memoized;
import org.jclouds.collect.TransformingSetSupplier;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.ComputeServiceContext;
@@ -41,10 +45,13 @@
import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
+import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
@@ -64,33 +71,39 @@
this.asyncClientType = asyncClientType;
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings( { "unchecked", "rawtypes" })
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<ComputeServiceContext>() {
- }).to((TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, syncClientType,
- asyncClientType))).in(Scopes.SINGLETON);
+ }).to(
+ (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class,
+ syncClientType, asyncClientType))).in(Scopes.SINGLETON);
+ }
+
+ @Override
+ protected void configureLocationModule() {
+ // configuring below
}
@Provides
@Singleton
- protected Supplier<Set<? extends Location>> provideLocations(final ComputeServiceAdapter<N, H, I, L> adapter,
- Function<L, Location> transformer) {
- return new TransformingSetSupplier<L, Location>(new Supplier<Iterable<L>>() {
-
- @Override
- public Iterable<L> get() {
- return adapter.listLocations();
- }
-
- }, transformer);
+ @Memoized
+ protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
+ final ComputeServiceAdapter<N, H, I, L> adapter, final Function<L, Location> transformer) {
+ return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException,
+ seconds, new Supplier<Set<? extends Location>>() {
+ @Override
+ public Set<? extends Location> get() {
+ return ImmutableSet.<Location> copyOf(Iterables.transform(adapter.listLocations(), transformer));
+ }
+ });
}
@Provides
@Singleton
protected Supplier<Set<? extends Hardware>> provideHardware(final ComputeServiceAdapter<N, H, I, L> adapter,
- Function<H, Hardware> transformer) {
+ Function<H, Hardware> transformer) {
return new TransformingSetSupplier<H, Hardware>(new Supplier<Iterable<H>>() {
@Override
@@ -104,7 +117,7 @@
@Provides
@Singleton
protected Supplier<Set<? extends Image>> provideImages(final ComputeServiceAdapter<N, H, I, L> adapter,
- Function<I, Image> transformer, AddDefaultCredentialsToImage addDefaultCredentialsToImage) {
+ Function<I, Image> transformer, AddDefaultCredentialsToImage addDefaultCredentialsToImage) {
return new TransformingSetSupplier<I, Image>(new Supplier<Iterable<I>>() {
@Override
@@ -139,7 +152,7 @@
@Provides
@Singleton
protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy(
- AdaptingComputeServiceStrategies<N, H, I, L> in) {
+ AdaptingComputeServiceStrategies<N, H, I, L> in) {
return in;
}
diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodePresentAndInIntendedState.java b/compute/src/main/java/org/jclouds/compute/predicates/NodePresentAndInIntendedState.java
index dd79eaa..eb7139d 100644
--- a/compute/src/main/java/org/jclouds/compute/predicates/NodePresentAndInIntendedState.java
+++ b/compute/src/main/java/org/jclouds/compute/predicates/NodePresentAndInIntendedState.java
@@ -25,9 +25,9 @@
import javax.annotation.Resource;
import javax.inject.Singleton;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
@@ -43,18 +43,18 @@
@Singleton
public class NodePresentAndInIntendedState implements Predicate<NodeMetadata> {
- private final ComputeService client;
+ private final GetNodeMetadataStrategy client;
private final NodeState intended;
private final Set<NodeState> invalids;
@Resource
protected Logger logger = Logger.NULL;
@Inject
- public NodePresentAndInIntendedState(NodeState intended, ComputeService client) {
+ public NodePresentAndInIntendedState(NodeState intended, GetNodeMetadataStrategy client) {
this(intended, ImmutableSet.of(NodeState.ERROR), client);
}
- public NodePresentAndInIntendedState(NodeState intended, Set<NodeState> invalids, ComputeService client) {
+ public NodePresentAndInIntendedState(NodeState intended, Set<NodeState> invalids, GetNodeMetadataStrategy client) {
this.intended = intended;
this.client = client;
this.invalids = invalids;
@@ -75,6 +75,6 @@
private NodeMetadata refresh(NodeMetadata node) {
if (node == null || node.getId() == null)
return null;
- return client.getNodeMetadata(node.getId());
+ return client.getNode(node.getId());
}
}
diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodeRunning.java b/compute/src/main/java/org/jclouds/compute/predicates/NodeRunning.java
index 0c03ce6..3811c7c 100644
--- a/compute/src/main/java/org/jclouds/compute/predicates/NodeRunning.java
+++ b/compute/src/main/java/org/jclouds/compute/predicates/NodeRunning.java
@@ -20,8 +20,8 @@
import javax.inject.Singleton;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
@@ -36,7 +36,7 @@
public class NodeRunning extends NodePresentAndInIntendedState {
@Inject
- public NodeRunning(ComputeService client) {
+ public NodeRunning(GetNodeMetadataStrategy client) {
super(NodeState.RUNNING, ImmutableSet.of(NodeState.ERROR, NodeState.TERMINATED), client);
}
}
diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodeSuspended.java b/compute/src/main/java/org/jclouds/compute/predicates/NodeSuspended.java
index f497453..f0dc578 100644
--- a/compute/src/main/java/org/jclouds/compute/predicates/NodeSuspended.java
+++ b/compute/src/main/java/org/jclouds/compute/predicates/NodeSuspended.java
@@ -20,8 +20,8 @@
import javax.inject.Singleton;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import com.google.inject.Inject;
@@ -35,7 +35,7 @@
public class NodeSuspended extends NodePresentAndInIntendedState {
@Inject
- public NodeSuspended(ComputeService client) {
+ public NodeSuspended(GetNodeMetadataStrategy client) {
super(NodeState.SUSPENDED, client);
}
}
diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodeTerminated.java b/compute/src/main/java/org/jclouds/compute/predicates/NodeTerminated.java
index 0cd90c4..b28bead 100644
--- a/compute/src/main/java/org/jclouds/compute/predicates/NodeTerminated.java
+++ b/compute/src/main/java/org/jclouds/compute/predicates/NodeTerminated.java
@@ -23,9 +23,9 @@
import javax.annotation.Resource;
import javax.inject.Singleton;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
@@ -40,13 +40,13 @@
@Singleton
public class NodeTerminated implements Predicate<NodeMetadata> {
- private final ComputeService client;
+ private final GetNodeMetadataStrategy client;
@Resource
protected Logger logger = Logger.NULL;
@Inject
- public NodeTerminated(ComputeService client) {
+ public NodeTerminated(GetNodeMetadataStrategy client) {
this.client = client;
}
@@ -61,6 +61,6 @@
}
private NodeMetadata refresh(NodeMetadata node) {
- return client.getNodeMetadata(node.getId());
+ return client.getNode(node.getId());
}
}
diff --git a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java
index 649a00a..7ffb562 100644
--- a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java
+++ b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java
@@ -39,6 +39,24 @@
public static final String PROPERTY_INIT_STATUS_INITIAL_PERIOD = "jclouds.compute.init-status.initial-period";
public static final String PROPERTY_INIT_STATUS_MAX_PERIOD = "jclouds.compute.init-status.max-period";
+
+ /**
+ * overrides the image specified in the subclass of {@link BaseComputeServiceContextModule#provideTemplate}
+ */
+ public static final String PROPERTY_IMAGE_ID = "jclouds.image-id";
+
+ /**
+ * username and, if colon delimited, password of the default user on the image that is or can become root
+ * <p/>
+ * ex. {@code ubuntu}
+ * ex. {@code toor:password}
+ */
+ public static final String PROPERTY_IMAGE_LOGIN_USER = "jclouds.image.login-user";
+
+ /**
+ * true if gaining a sudo shell requires a password
+ */
+ public static final String PROPERTY_IMAGE_AUTHENTICATE_SUDO = "jclouds.image.authenticate-sudo";
/**
* comma-separated nodes that we shouldn't attempt to list as they are dead
diff --git a/compute/src/main/java/org/jclouds/ssh/SshClient.java b/compute/src/main/java/org/jclouds/ssh/SshClient.java
index 5b2730b..894b69b 100644
--- a/compute/src/main/java/org/jclouds/ssh/SshClient.java
+++ b/compute/src/main/java/org/jclouds/ssh/SshClient.java
@@ -18,9 +18,6 @@
*/
package org.jclouds.ssh;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.LoginCredentials;
@@ -56,10 +53,8 @@
ExecResponse exec(String command);
- @PostConstruct
void connect();
- @PreDestroy
void disconnect();
void put(String path, String contents);
diff --git a/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java
index a01c053..c02573e 100644
--- a/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java
+++ b/compute/src/test/java/org/jclouds/compute/BaseVersionedServiceLiveTest.java
@@ -18,15 +18,11 @@
*/
package org.jclouds.compute;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Strings.emptyToNull;
-
import java.util.Properties;
-import org.jclouds.Constants;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.domain.LoginCredentials.Builder;
-import org.jclouds.rest.RestContextFactory;
+import org.jclouds.rest.BaseRestClientLiveTest;
import org.testng.annotations.BeforeClass;
import com.google.common.base.Splitter;
@@ -36,42 +32,16 @@
*
* @author Jason King
*/
-public abstract class BaseVersionedServiceLiveTest {
- protected String prefix = System.getProperty("user.name");
+public abstract class BaseVersionedServiceLiveTest extends BaseRestClientLiveTest {
- protected String provider;
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected String imageId;
protected String loginUser;
protected String authenticateSudo;
protected LoginCredentials loginCredentials = LoginCredentials.builder().user("root").build();
- protected Properties setupRestProperties() {
- return RestContextFactory.getPropertiesFromResource("/rest.properties");
- }
-
+ @Override
protected Properties setupProperties() {
-
- if (emptyToNull(provider) == null)
- throw new NullPointerException("provider must not be null or empty:" + provider);
- if (emptyToNull(identity) == null)
- throw new NullPointerException("identity must not be null or empty:" + provider);
-
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
-
- overrides.setProperty(provider + ".identity", identity);
-
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ Properties overrides= super.setupProperties();
if (imageId != null)
overrides.setProperty(provider + ".image-id", imageId);
if (loginUser != null)
@@ -84,10 +54,7 @@
@BeforeClass
protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ super.setupCredentials();
imageId = System.getProperty("test." + provider + ".image-id");
loginUser = System.getProperty("test." + provider + ".image.login-user");
authenticateSudo = System.getProperty("test." + provider + ".image.authenticate-sudo");
diff --git a/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java b/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java
index fcc5ad3..af977d5 100644
--- a/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java
+++ b/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java
@@ -43,7 +43,7 @@
@SuppressWarnings("rawtypes")
ComputeServiceContext context = new ComputeServiceContextFactory()
.createContext(new StandaloneComputeServiceContextSpec<ConcurrentMap, NodeMetadata, Hardware, Image, Location>(
- "stub", "stub", "1", "", "identity", "credential", ConcurrentMap.class,
+ "stub", "stub", "1", "", "", "identity", "credential", ConcurrentMap.class,
StubComputeServiceContextBuilder.class, ImmutableSet.<Module> of()));
context.getComputeService().listNodes();
diff --git a/compute/src/test/java/org/jclouds/compute/predicates/NodePredicatesTest.java b/compute/src/test/java/org/jclouds/compute/predicates/NodePredicatesTest.java
index 0abfcd9..4d55df7 100644
--- a/compute/src/test/java/org/jclouds/compute/predicates/NodePredicatesTest.java
+++ b/compute/src/test/java/org/jclouds/compute/predicates/NodePredicatesTest.java
@@ -22,9 +22,9 @@
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
-import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@@ -38,15 +38,15 @@
public class NodePredicatesTest {
private NodeMetadata node;
- private ComputeService computeService;
+ private GetNodeMetadataStrategy computeService;
@BeforeMethod
public void setUp() throws Exception {
node = createMock(NodeMetadata.class);
- computeService = createMock(ComputeService.class);
+ computeService = createMock(GetNodeMetadataStrategy.class);
expect(node.getId()).andReturn("myid").anyTimes();
- expect(computeService.getNodeMetadata("myid")).andReturn(node).anyTimes();
+ expect(computeService.getNode("myid")).andReturn(node).anyTimes();
expect(node.getLocation()).andReturn(null).anyTimes();
}
diff --git a/core/pom.xml b/core/pom.xml
index e395f78..ebb06b6 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -142,8 +142,7 @@
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
- <Export-Package>com.google.gson;-split-package:=merge-first,
- org.jclouds.*;version=${project.version}</Export-Package>
+ <Export-Package>org.jclouds.*;version=${project.version}</Export-Package>
<DynamicImport-Package>org.jclouds.*</DynamicImport-Package>
</instructions>
</configuration>
diff --git a/core/src/main/java/com/google/gson/internal/Streams.java b/core/src/main/java/com/google/gson/internal/Streams.java
deleted file mode 100644
index 0459793..0000000
--- a/core/src/main/java/com/google/gson/internal/Streams.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * 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.gson.internal;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonIOException;
-import com.google.gson.JsonNull;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSyntaxException;
-import com.google.gson.internal.bind.TypeAdapters;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-import com.google.gson.stream.MalformedJsonException;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.Writer;
-
-import org.jclouds.json.internal.JsonLiteral;
-
-/**
- * Reads and writes GSON parse trees over streams.
- */
-public final class Streams {
- /**
- * Takes a reader in any state and returns the next value as a JsonElement.
- */
- public static JsonElement parse(JsonReader reader) throws JsonParseException {
- boolean isEmpty = true;
- try {
- reader.peek();
- isEmpty = false;
- return TypeAdapters.JSON_ELEMENT.read(reader);
- } catch (EOFException e) {
- /*
- * For compatibility with JSON 1.5 and earlier, we return a JsonNull for
- * empty documents instead of throwing.
- */
- if (isEmpty) {
- return JsonNull.INSTANCE;
- }
- throw new JsonIOException(e);
- } catch (MalformedJsonException e) {
- throw new JsonSyntaxException(e);
- } catch (IOException e) {
- throw new JsonIOException(e);
- } catch (NumberFormatException e) {
- throw new JsonSyntaxException(e);
- }
- }
-
- /**
- * Writes the JSON element to the writer, recursively.
- */
- public static void write(JsonElement element, JsonWriter writer) throws IOException {
- //BEGIN JCLOUDS PATCH
- // * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
- if (element instanceof JsonLiteral ) {
- writer.value(JsonLiteral.class.cast(element));
- //END JCLOUDS PATCH
- } else {
- TypeAdapters.JSON_ELEMENT.write(writer, element);
- }
- }
-
- public static Writer writerForAppendable(Appendable appendable) {
- return appendable instanceof Writer ? (Writer) appendable : new AppendableWriter(appendable);
- }
-
- /**
- * Adapts an {@link Appendable} so it can be passed anywhere a {@link Writer}
- * is used.
- */
- private static class AppendableWriter extends Writer {
- private final Appendable appendable;
- private final CurrentWrite currentWrite = new CurrentWrite();
-
- private AppendableWriter(Appendable appendable) {
- this.appendable = appendable;
- }
-
- @Override public void write(char[] chars, int offset, int length) throws IOException {
- currentWrite.chars = chars;
- appendable.append(currentWrite, offset, offset + length);
- }
-
- @Override public void write(int i) throws IOException {
- appendable.append((char) i);
- }
-
- @Override public void flush() {}
- @Override public void close() {}
-
- /**
- * A mutable char sequence pointing at a single char[].
- */
- static class CurrentWrite implements CharSequence {
- char[] chars;
- public int length() {
- return chars.length;
- }
- public char charAt(int i) {
- return chars[i];
- }
- public CharSequence subSequence(int start, int end) {
- return new String(chars, start, end - start);
- }
- }
- }
-
-}
diff --git a/core/src/main/java/com/google/gson/stream/JsonWriter.java b/core/src/main/java/com/google/gson/stream/JsonWriter.java
deleted file mode 100644
index c5996e9..0000000
--- a/core/src/main/java/com/google/gson/stream/JsonWriter.java
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * 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.gson.stream;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jclouds.json.internal.JsonLiteral;
-
-
-/**
- * Writes a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
- * encoded value to a stream, one token at a time. The stream includes both
- * literal values (strings, numbers, booleans and nulls) as well as the begin
- * and end delimiters of objects and arrays.
- *
- * <h3>Encoding JSON</h3>
- * To encode your data as JSON, create a new {@code JsonWriter}. Each JSON
- * document must contain one top-level array or object. Call methods on the
- * writer as you walk the structure's contents, nesting arrays and objects as
- * necessary:
- * <ul>
- * <li>To write <strong>arrays</strong>, first call {@link #beginArray()}.
- * Write each of the array's elements with the appropriate {@link #value}
- * methods or by nesting other arrays and objects. Finally close the array
- * using {@link #endArray()}.
- * <li>To write <strong>objects</strong>, first call {@link #beginObject()}.
- * Write each of the object's properties by alternating calls to
- * {@link #name} with the property's value. Write property values with the
- * appropriate {@link #value} method or by nesting other objects or arrays.
- * Finally close the object using {@link #endObject()}.
- * </ul>
- *
- * <h3>Example</h3>
- * Suppose we'd like to encode a stream of messages such as the following: <pre> {@code
- * [
- * {
- * "id": 912345678901,
- * "text": "How do I stream JSON in Java?",
- * "geo": null,
- * "user": {
- * "name": "json_newb",
- * "followers_count": 41
- * }
- * },
- * {
- * "id": 912345678902,
- * "text": "@json_newb just use JsonWriter!",
- * "geo": [50.454722, -104.606667],
- * "user": {
- * "name": "jesse",
- * "followers_count": 2
- * }
- * }
- * ]}</pre>
- * This code encodes the above structure: <pre> {@code
- * public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
- * JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
- * writer.setIndentSpaces(4);
- * writeMessagesArray(writer, messages);
- * writer.close();
- * }
- *
- * public void writeMessagesArray(JsonWriter writer, List<Message> messages) throws IOException {
- * writer.beginArray();
- * for (Message message : messages) {
- * writeMessage(writer, message);
- * }
- * writer.endArray();
- * }
- *
- * public void writeMessage(JsonWriter writer, Message message) throws IOException {
- * writer.beginObject();
- * writer.name("id").value(message.getId());
- * writer.name("text").value(message.getText());
- * if (message.getGeo() != null) {
- * writer.name("geo");
- * writeDoublesArray(writer, message.getGeo());
- * } else {
- * writer.name("geo").nullValue();
- * }
- * writer.name("user");
- * writeUser(writer, message.getUser());
- * writer.endObject();
- * }
- *
- * public void writeUser(JsonWriter writer, User user) throws IOException {
- * writer.beginObject();
- * writer.name("name").value(user.getName());
- * writer.name("followers_count").value(user.getFollowersCount());
- * writer.endObject();
- * }
- *
- * public void writeDoublesArray(JsonWriter writer, List<Double> doubles) throws IOException {
- * writer.beginArray();
- * for (Double value : doubles) {
- * writer.value(value);
- * }
- * writer.endArray();
- * }}</pre>
- *
- * <p>Each {@code JsonWriter} may be used to write a single JSON stream.
- * Instances of this class are not thread safe. Calls that would result in a
- * malformed JSON string will fail with an {@link IllegalStateException}.
- *
- * @author Jesse Wilson
- * @since 1.6
- */
-public class JsonWriter implements Closeable {
-
- /** The output data, containing at most one top-level array or object. */
- private final Writer out;
-
- private final List<JsonScope> stack = new ArrayList<JsonScope>();
- {
- stack.add(JsonScope.EMPTY_DOCUMENT);
- }
-
- /**
- * A string containing a full set of spaces for a single level of
- * indentation, or null for no pretty printing.
- */
- private String indent;
-
- /**
- * The name/value separator; either ":" or ": ".
- */
- private String separator = ":";
-
- private boolean lenient;
-
- private boolean htmlSafe;
-
- private String deferredName;
-
- private boolean serializeNulls = true;
-
- /**
- * Creates a new instance that writes a JSON-encoded stream to {@code out}.
- * For best performance, ensure {@link Writer} is buffered; wrapping in
- * {@link java.io.BufferedWriter BufferedWriter} if necessary.
- */
- public JsonWriter(Writer out) {
- if (out == null) {
- throw new NullPointerException("out == null");
- }
- this.out = out;
- }
-
- /**
- * Sets the indentation string to be repeated for each level of indentation
- * in the encoded document. If {@code indent.isEmpty()} the encoded document
- * will be compact. Otherwise the encoded document will be more
- * human-readable.
- *
- * @param indent a string containing only whitespace.
- */
- public final void setIndent(String indent) {
- if (indent.length() == 0) {
- this.indent = null;
- this.separator = ":";
- } else {
- this.indent = indent;
- this.separator = ": ";
- }
- }
-
- /**
- * Configure this writer to relax its syntax rules. By default, this writer
- * only emits well-formed JSON as specified by <a
- * href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>. Setting the writer
- * to lenient permits the following:
- * <ul>
- * <li>Top-level values of any type. With strict writing, the top-level
- * value must be an object or an array.
- * <li>Numbers may be {@link Double#isNaN() NaNs} or {@link
- * Double#isInfinite() infinities}.
- * </ul>
- */
- public final void setLenient(boolean lenient) {
- this.lenient = lenient;
- }
-
- /**
- * Returns true if this writer has relaxed syntax rules.
- */
- public boolean isLenient() {
- return lenient;
- }
-
- /**
- * Configure this writer to emit JSON that's safe for direct inclusion in HTML
- * and XML documents. This escapes the HTML characters {@code <}, {@code >},
- * {@code &} and {@code =} before writing them to the stream. Without this
- * setting, your XML/HTML encoder should replace these characters with the
- * corresponding escape sequences.
- */
- public final void setHtmlSafe(boolean htmlSafe) {
- this.htmlSafe = htmlSafe;
- }
-
- /**
- * Returns true if this writer writes JSON that's safe for inclusion in HTML
- * and XML documents.
- */
- public final boolean isHtmlSafe() {
- return htmlSafe;
- }
-
- /**
- * Sets whether object members are serialized when their value is null.
- * This has no impact on array elements. The default is true.
- */
- public final void setSerializeNulls(boolean serializeNulls) {
- this.serializeNulls = serializeNulls;
- }
-
- /**
- * Returns true if object members are serialized when their value is null.
- * This has no impact on array elements. The default is true.
- */
- public final boolean getSerializeNulls() {
- return serializeNulls;
- }
-
- /**
- * Begins encoding a new array. Each call to this method must be paired with
- * a call to {@link #endArray}.
- *
- * @return this writer.
- */
- public JsonWriter beginArray() throws IOException {
- writeDeferredName();
- return open(JsonScope.EMPTY_ARRAY, "[");
- }
-
- /**
- * Ends encoding the current array.
- *
- * @return this writer.
- */
- public JsonWriter endArray() throws IOException {
- return close(JsonScope.EMPTY_ARRAY, JsonScope.NONEMPTY_ARRAY, "]");
- }
-
- /**
- * Begins encoding a new object. Each call to this method must be paired
- * with a call to {@link #endObject}.
- *
- * @return this writer.
- */
- public JsonWriter beginObject() throws IOException {
- writeDeferredName();
- return open(JsonScope.EMPTY_OBJECT, "{");
- }
-
- /**
- * Ends encoding the current object.
- *
- * @return this writer.
- */
- public JsonWriter endObject() throws IOException {
- return close(JsonScope.EMPTY_OBJECT, JsonScope.NONEMPTY_OBJECT, "}");
- }
-
- /**
- * Enters a new scope by appending any necessary whitespace and the given
- * bracket.
- */
- private JsonWriter open(JsonScope empty, String openBracket) throws IOException {
- beforeValue(true);
- stack.add(empty);
- out.write(openBracket);
- return this;
- }
-
- /**
- * Closes the current scope by appending any necessary whitespace and the
- * given bracket.
- */
- private JsonWriter close(JsonScope empty, JsonScope nonempty, String closeBracket)
- throws IOException {
- JsonScope context = peek();
- if (context != nonempty && context != empty) {
- throw new IllegalStateException("Nesting problem: " + stack);
- }
- if (deferredName != null) {
- throw new IllegalStateException("Dangling name: " + deferredName);
- }
-
- stack.remove(stack.size() - 1);
- if (context == nonempty) {
- newline();
- }
- out.write(closeBracket);
- return this;
- }
-
- /**
- * Returns the value on the top of the stack.
- */
- private JsonScope peek() {
- return stack.get(stack.size() - 1);
- }
-
- /**
- * Replace the value on the top of the stack with the given value.
- */
- private void replaceTop(JsonScope topOfStack) {
- stack.set(stack.size() - 1, topOfStack);
- }
-
- /**
- * Encodes the property name.
- *
- * @param name the name of the forthcoming value. May not be null.
- * @return this writer.
- */
- public JsonWriter name(String name) throws IOException {
- if (name == null) {
- throw new NullPointerException("name == null");
- }
- if (deferredName != null) {
- throw new IllegalStateException();
- }
- deferredName = name;
- return this;
- }
-
- private void writeDeferredName() throws IOException {
- if (deferredName != null) {
- beforeName();
- string(deferredName);
- deferredName = null;
- }
- }
-
- /**
- * Encodes {@code value}.
- *
- * @param value the literal string value, or null to encode a null literal.
- * @return this writer.
- */
- public JsonWriter value(String value) throws IOException {
- if (value == null) {
- return nullValue();
- }
- writeDeferredName();
- beforeValue(false);
- string(value);
- return this;
- }
-
- /**
- * Encodes {@code null}.
- *
- * @return this writer.
- */
- public JsonWriter nullValue() throws IOException {
- if (deferredName != null) {
- if (serializeNulls) {
- writeDeferredName();
- } else {
- deferredName = null;
- return this; // skip the name and the value
- }
- }
- beforeValue(false);
- out.write("null");
- return this;
- }
-//BEGIN JCLOUDS PATCH
-//* @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
- /**
- * Writes {@code value} literally
- *
- * @return this writer.
- */
- public JsonWriter value(JsonLiteral value) throws IOException {
- if (value == null) {
- return nullValue();
- }
- writeDeferredName();
- beforeValue(false);
- out.write(value.toString());
- return this;
- }
-//END JCLOUDS PATCH
- /**
- * Encodes {@code value}.
- *
- * @return this writer.
- */
- public JsonWriter value(boolean value) throws IOException {
- writeDeferredName();
- beforeValue(false);
- out.write(value ? "true" : "false");
- return this;
- }
-
- /**
- * Encodes {@code value}.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this writer.
- */
- public JsonWriter value(double value) throws IOException {
- if (Double.isNaN(value) || Double.isInfinite(value)) {
- throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
- }
- writeDeferredName();
- beforeValue(false);
- out.append(Double.toString(value));
- return this;
- }
-
- /**
- * Encodes {@code value}.
- *
- * @return this writer.
- */
- public JsonWriter value(long value) throws IOException {
- writeDeferredName();
- beforeValue(false);
- out.write(Long.toString(value));
- return this;
- }
-
- /**
- * Encodes {@code value}.
- *
- * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
- * {@link Double#isInfinite() infinities}.
- * @return this writer.
- */
- public JsonWriter value(Number value) throws IOException {
- if (value == null) {
- return nullValue();
- }
-
- writeDeferredName();
- String string = value.toString();
- if (!lenient
- && (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN"))) {
- throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
- }
- beforeValue(false);
- out.append(string);
- return this;
- }
-
- /**
- * Ensures all buffered data is written to the underlying {@link Writer}
- * and flushes that writer.
- */
- public void flush() throws IOException {
- out.flush();
- }
-
- /**
- * Flushes and closes this writer and the underlying {@link Writer}.
- *
- * @throws IOException if the JSON document is incomplete.
- */
- public void close() throws IOException {
- out.close();
-
- if (peek() != JsonScope.NONEMPTY_DOCUMENT) {
- throw new IOException("Incomplete document");
- }
- }
-
- private void string(String value) throws IOException {
- out.write("\"");
- for (int i = 0, length = value.length(); i < length; i++) {
- char c = value.charAt(i);
-
- /*
- * From RFC 4627, "All Unicode characters may be placed within the
- * quotation marks except for the characters that must be escaped:
- * quotation mark, reverse solidus, and the control characters
- * (U+0000 through U+001F)."
- *
- * We also escape '\u2028' and '\u2029', which JavaScript interprets as
- * newline characters. This prevents eval() from failing with a syntax
- * error. http://code.google.com/p/google-gson/issues/detail?id=341
- */
- switch (c) {
- case '"':
- case '\\':
- out.write('\\');
- out.write(c);
- break;
-
- case '\t':
- out.write("\\t");
- break;
-
- case '\b':
- out.write("\\b");
- break;
-
- case '\n':
- out.write("\\n");
- break;
-
- case '\r':
- out.write("\\r");
- break;
-
- case '\f':
- out.write("\\f");
- break;
-
- case '<':
- case '>':
- case '&':
- case '=':
- case '\'':
- if (htmlSafe) {
- out.write(String.format("\\u%04x", (int) c));
- } else {
- out.write(c);
- }
- break;
-
- case '\u2028':
- case '\u2029':
- out.write(String.format("\\u%04x", (int) c));
- break;
-
- default:
- if (c <= 0x1F) {
- out.write(String.format("\\u%04x", (int) c));
- } else {
- out.write(c);
- }
- break;
- }
- }
- out.write("\"");
- }
-
- private void newline() throws IOException {
- if (indent == null) {
- return;
- }
-
- out.write("\n");
- for (int i = 1; i < stack.size(); i++) {
- out.write(indent);
- }
- }
-
- /**
- * Inserts any necessary separators and whitespace before a name. Also
- * adjusts the stack to expect the name's value.
- */
- private void beforeName() throws IOException {
- JsonScope context = peek();
- if (context == JsonScope.NONEMPTY_OBJECT) { // first in object
- out.write(',');
- } else if (context != JsonScope.EMPTY_OBJECT) { // not in an object!
- throw new IllegalStateException("Nesting problem: " + stack);
- }
- newline();
- replaceTop(JsonScope.DANGLING_NAME);
- }
-
- /**
- * Inserts any necessary separators and whitespace before a literal value,
- * inline array, or inline object. Also adjusts the stack to expect either a
- * closing bracket or another element.
- *
- * @param root true if the value is a new array or object, the two values
- * permitted as top-level elements.
- */
- private void beforeValue(boolean root) throws IOException {
- switch (peek()) {
- case EMPTY_DOCUMENT: // first in document
- if (!lenient && !root) {
- throw new IllegalStateException(
- "JSON must start with an array or an object.");
- }
- replaceTop(JsonScope.NONEMPTY_DOCUMENT);
- break;
-
- case EMPTY_ARRAY: // first in array
- replaceTop(JsonScope.NONEMPTY_ARRAY);
- newline();
- break;
-
- case NONEMPTY_ARRAY: // another in array
- out.append(',');
- newline();
- break;
-
- case DANGLING_NAME: // value for name
- out.append(separator);
- replaceTop(JsonScope.NONEMPTY_OBJECT);
- break;
-
- case NONEMPTY_DOCUMENT:
- throw new IllegalStateException(
- "JSON must have only one top-level value.");
-
- default:
- throw new IllegalStateException("Nesting problem: " + stack);
- }
- }
-}
diff --git a/core/src/main/java/org/jclouds/Constants.java b/core/src/main/java/org/jclouds/Constants.java
index 2052da0..cc81d4d 100644
--- a/core/src/main/java/org/jclouds/Constants.java
+++ b/core/src/main/java/org/jclouds/Constants.java
@@ -191,7 +191,7 @@
public static final String PROPERTY_API = "jclouds.api";
/**
- * String property.
+ * String property. default empty string
* <p/>
* Explicitly identifies the version of an api.
*/
@@ -200,6 +200,17 @@
/**
* String property.
* <p/>
+ * Explicitly identifies the build that the server jclouds connects to is running.
+ *
+ * For example, for virtualbox, the api version may be {@code 4.1.8} while the build version is
+ * {@code 4.1.8r75467}. Or a vcloud endpoint may be api version {@code 1.0} while the build is
+ * {@code 1.5.0.0.124312}
+ */
+ public static final String PROPERTY_BUILD_VERSION = "jclouds.build-version";
+
+ /**
+ * String property.
+ * <p/>
* Explicitly identifies the most top-level endpoint to a service provider. This helps
* differentiate two providers of the same api, or a different environments providing the same
* api.
diff --git a/core/src/main/java/org/jclouds/JcloudsVersion.java b/core/src/main/java/org/jclouds/JcloudsVersion.java
new file mode 100644
index 0000000..ec36b1f
--- /dev/null
+++ b/core/src/main/java/org/jclouds/JcloudsVersion.java
@@ -0,0 +1,106 @@
+/**
+ * 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;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * @author Andrew Phillips
+ */
+public class JcloudsVersion {
+ @VisibleForTesting
+ static final String VERSION_RESOURCE_FILE = "META-INF/maven/org.jclouds/jclouds-core/pom.properties";
+ private static final String VERSION_PROPERTY_NAME = "version";
+
+ // TODO: stop supporting x.y.z-rc-n after the 1.3.0 release
+ // x.y.z or x.y.z-rc.n or x.y.z-rc-n, optionally with -SNAPSHOT suffix - see http://semver.org
+ private static final Pattern SEMANTIC_VERSION_PATTERN =
+ Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-rc[-\\.](\\d+))?(?:-SNAPSHOT)?");
+
+ private static final JcloudsVersion INSTANCE = new JcloudsVersion();
+
+ public final int majorVersion;
+ public final int minorVersion;
+ public final int patchVersion;
+ public final boolean releaseCandidate;
+ private final String version;
+
+ /**
+ * Non-null iff {@link #releaseCandidate} is {@code true}
+ */
+ public final @Nullable Integer releaseCandidateVersion;
+ public final boolean snapshot;
+
+ @VisibleForTesting
+ JcloudsVersion() {
+ this(readVersionPropertyFromClasspath());
+ }
+
+ private static String readVersionPropertyFromClasspath() {
+ Properties versionProperties = new Properties();
+ try {
+ versionProperties.load(checkNotNull(Thread.currentThread().getContextClassLoader().getResourceAsStream(VERSION_RESOURCE_FILE), VERSION_RESOURCE_FILE));
+ } catch (IOException exception) {
+ throw new IllegalStateException(format("Unable to load version resource file '%s'", VERSION_RESOURCE_FILE), exception);
+ }
+ return checkNotNull(versionProperties.getProperty(VERSION_PROPERTY_NAME), VERSION_PROPERTY_NAME);
+ }
+
+ @VisibleForTesting
+ JcloudsVersion(String version) {
+ Matcher versionMatcher = SEMANTIC_VERSION_PATTERN.matcher(version);
+ checkArgument(versionMatcher.matches(), "Version '%s' did not match expected pattern '%s'",
+ version, SEMANTIC_VERSION_PATTERN);
+ this.version = version;
+ // a match will produce three or four matching groups (release candidate version optional)
+ majorVersion = Integer.valueOf(versionMatcher.group(1));
+ minorVersion = Integer.valueOf(versionMatcher.group(2));
+ patchVersion = Integer.valueOf(versionMatcher.group(3));
+ String releaseCandidateVersionIfPresent = versionMatcher.group(4);
+ if (releaseCandidateVersionIfPresent != null) {
+ releaseCandidate = true;
+ releaseCandidateVersion = Integer.valueOf(releaseCandidateVersionIfPresent);
+ } else {
+ releaseCandidate = false;
+ releaseCandidateVersion = null;
+ }
+ // endsWith("T") would be cheaper but we only do this once...
+ snapshot = version.endsWith("-SNAPSHOT");
+ }
+
+ @Override
+ public String toString() {
+ return version;
+ }
+
+ public static JcloudsVersion get() {
+ return INSTANCE;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/org/jclouds/PropertiesBuilder.java b/core/src/main/java/org/jclouds/PropertiesBuilder.java
index 3029a68..f79a1cd 100644
--- a/core/src/main/java/org/jclouds/PropertiesBuilder.java
+++ b/core/src/main/java/org/jclouds/PropertiesBuilder.java
@@ -19,6 +19,7 @@
package org.jclouds;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
+import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
@@ -218,6 +219,7 @@
props.setProperty(PROPERTY_CONNECTION_TIMEOUT, 60000 + "");
props.setProperty(PROPERTY_IO_WORKER_THREADS, 20 + "");
props.setProperty(PROPERTY_USER_THREADS, 0 + "");
+ props.setProperty(PROPERTY_BUILD_VERSION, "");
props.setProperty(PROPERTY_MAX_CONNECTION_REUSE, 75 + "");
props.setProperty(PROPERTY_MAX_SESSION_FAILURES, 2 + "");
props.setProperty(PROPERTY_SESSION_INTERVAL, 60 + "");
@@ -249,6 +251,11 @@
return this;
}
+ public PropertiesBuilder buildVersion(String buildVersion) {
+ properties.setProperty(PROPERTY_BUILD_VERSION, buildVersion);
+ return this;
+ }
+
public PropertiesBuilder credentials(String identity, @Nullable String credential) {
properties.setProperty(PROPERTY_IDENTITY, identity);
if (credential != null)
diff --git a/core/src/main/java/org/jclouds/crypto/Pems.java b/core/src/main/java/org/jclouds/crypto/Pems.java
index 76b8bb6..55740ed 100644
--- a/core/src/main/java/org/jclouds/crypto/Pems.java
+++ b/core/src/main/java/org/jclouds/crypto/Pems.java
@@ -42,11 +42,11 @@
import net.oauth.signature.pem.PEMReader;
import net.oauth.signature.pem.PKCS1EncodedKeySpec;
-import net.oauth.signature.pem.PKCS1EncodedPublicKeySpec;
import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import org.jclouds.crypto.Pems.PemProcessor.ResultParser;
+import org.jclouds.crypto.pem.PKCS1EncodedPublicKeySpec;
import org.jclouds.io.InputSuppliers;
import com.google.common.annotations.Beta;
diff --git a/core/src/main/java/net/oauth/signature/pem/PKCS1EncodedPublicKeySpec.java b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java
similarity index 68%
rename from core/src/main/java/net/oauth/signature/pem/PKCS1EncodedPublicKeySpec.java
rename to core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java
index 3b25774..a075378 100644
--- a/core/src/main/java/net/oauth/signature/pem/PKCS1EncodedPublicKeySpec.java
+++ b/core/src/main/java/org/jclouds/crypto/pem/PKCS1EncodedPublicKeySpec.java
@@ -41,15 +41,15 @@
*
****************************************************************************/
-package net.oauth.signature.pem;
+package org.jclouds.crypto.pem;
import java.io.IOException;
-import java.math.BigInteger;
import java.security.spec.RSAPublicKeySpec;
+import net.oauth.signature.pem.PKCS1EncodedKeySpec;
+
/**
- * PKCS#1 encoded public key spec. In oauth package as they made all classes
- * package visible.
+ * PKCS#1 encoded public key spec.
*
*
* @author Adrian Cole
@@ -79,41 +79,12 @@
}
/**
- * Decode PKCS#1 encoded private key into RSAPublicKeySpec.
- *
- * <p/>
- * The ASN.1 syntax for the private key with CRT is
- *
- * <pre>
- * --
- * -- Representation of RSA private key with information for the CRT algorithm.
- * --
- * RSAPrivateKey ::= SEQUENCE {
- * version Version,
- * modulus INTEGER, -- n
- * publicExponent INTEGER, -- e
- * }
- * </pre>
- *
- * @param keyBytes
- * PKCS#1 encoded key
- * @throws IOException
+ * get the modulus and public exponent by reusing {@link PKCS1EncodedKeySpec}
*/
-
private void decode(byte[] keyBytes) throws IOException {
+ PKCS1EncodedKeySpec privateSpec = new PKCS1EncodedKeySpec(keyBytes);
- DerParser parser = new DerParser(keyBytes);
-
- Asn1Object sequence = parser.read();
- if (sequence.getType() != DerParser.SEQUENCE)
- throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$
-
- // Parse inside the sequence
- parser = sequence.getParser();
-
- BigInteger modulus = parser.read().getInteger();
- BigInteger publicExp = parser.read().getInteger();
-
- keySpec = new RSAPublicKeySpec(modulus, publicExp);
+ keySpec = new RSAPublicKeySpec(privateSpec.getKeySpec().getModulus(), privateSpec.getKeySpec()
+ .getPublicExponent());
}
}
diff --git a/core/src/main/java/org/jclouds/domain/JsonBall.java b/core/src/main/java/org/jclouds/domain/JsonBall.java
index b8fa6fb..42c7a1a 100644
--- a/core/src/main/java/org/jclouds/domain/JsonBall.java
+++ b/core/src/main/java/org/jclouds/domain/JsonBall.java
@@ -75,13 +75,18 @@
public JsonBall(long value) {
this.value = value + "";
}
-
- public JsonBall(String value) {
- this.value = quoteStringIfNotNumber(checkNotNull(value, "value"));
+
+ public JsonBall(boolean value) {
+ this.value = value + "";
}
- static String quoteStringIfNotNumber(String in) {
- if (Patterns.JSON_STRING_PATTERN.matcher(in).find() && !Patterns.JSON_NUMBER_PATTERN.matcher(in).find()) {
+ public JsonBall(String value) {
+ this.value = quoteStringIfNotNumberOrBoolean(checkNotNull(value, "value"));
+ }
+
+ static String quoteStringIfNotNumberOrBoolean(String in) {
+ if (Patterns.JSON_STRING_PATTERN.matcher(in).find() && !Patterns.JSON_NUMBER_PATTERN.matcher(in).find()
+ && !Patterns.JSON_BOOLEAN_PATTERN.matcher(in).find()) {
return "\"" + in + "\"";
}
return in;
diff --git a/core/src/main/java/org/jclouds/http/HttpRequest.java b/core/src/main/java/org/jclouds/http/HttpRequest.java
index 340ab88..67c7ab7 100644
--- a/core/src/main/java/org/jclouds/http/HttpRequest.java
+++ b/core/src/main/java/org/jclouds/http/HttpRequest.java
@@ -22,13 +22,12 @@
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
-import java.util.Arrays;
import java.util.List;
+import org.jclouds.io.Payload;
import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.io.Payload;
-
+import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
@@ -191,55 +190,26 @@
public Builder toBuilder() {
return Builder.from(this);
}
-
+
@Override
public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + ((endpoint == null) ? 0 : endpoint.hashCode());
- result = prime * result + ((method == null) ? 0 : method.hashCode());
- result = prime * result + ((payload == null) ? 0 : payload.hashCode());
- result = prime * result + ((headers == null) ? 0 : headers.hashCode());
- result = prime * result + ((requestFilters == null) ? 0 : requestFilters.hashCode());
- result = prime * result + Arrays.hashCode(skips);
- return result;
+ return Objects.hashCode(method, endpoint, headers, payload);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
- if (!super.equals(obj))
- return false;
- if (getClass() != obj.getClass())
+ if (!(obj instanceof HttpRequest))
return false;
HttpRequest other = (HttpRequest) obj;
- if (endpoint == null) {
- if (other.endpoint != null)
- return false;
- } else if (!endpoint.equals(other.endpoint))
+ if (!Objects.equal(method, other.method))
return false;
- if (method == null) {
- if (other.method != null)
- return false;
- } else if (!method.equals(other.method))
+ if (!Objects.equal(endpoint, other.endpoint))
return false;
- if (payload == null) {
- if (other.payload != null)
- return false;
- } else if (!payload.equals(other.payload))
+ if (!Objects.equal(headers, other.headers))
return false;
- if (headers == null) {
- if (other.headers != null)
- return false;
- } else if (!headers.equals(other.headers))
- return false;
- if (requestFilters == null) {
- if (other.requestFilters != null)
- return false;
- } else if (!requestFilters.equals(other.requestFilters))
- return false;
- if (!Arrays.equals(skips, other.skips))
+ if (!Objects.equal(payload, other.payload))
return false;
return true;
}
diff --git a/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorService.java b/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorService.java
index 36f15a8..317b899 100644
--- a/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorService.java
+++ b/core/src/main/java/org/jclouds/http/TransformingHttpCommandExecutorService.java
@@ -22,6 +22,7 @@
import com.google.common.base.Function;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.inject.ImplementedBy;
/**
* Executor which will invoke and transform the response of an {@code EndpointCommand} into generic
@@ -29,6 +30,7 @@
*
* @author Adrian Cole
*/
+@ImplementedBy(TransformingHttpCommandExecutorServiceImpl.class)
public interface TransformingHttpCommandExecutorService {
/**
*
diff --git a/core/src/main/java/org/jclouds/http/TransformingHttpCommandImpl.java b/core/src/main/java/org/jclouds/http/TransformingHttpCommandImpl.java
index 0a26430..90f5de6 100644
--- a/core/src/main/java/org/jclouds/http/TransformingHttpCommandImpl.java
+++ b/core/src/main/java/org/jclouds/http/TransformingHttpCommandImpl.java
@@ -29,6 +29,7 @@
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.base.Function;
+import com.google.common.base.Objects;
import com.google.common.util.concurrent.ListenableFuture;
/**
@@ -145,6 +146,20 @@
}
@Override
+ public int hashCode() {
+ return Objects.hashCode(request);
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (!(that instanceof HttpCommand))
+ return false;
+ return Objects.equal(this.request, HttpCommand.class.cast(that).getCurrentRequest());
+ }
+
+ @Override
public String toString() {
if (request instanceof GeneratedHttpRequest<?>)
return String.format("[method=%s.%s, request=%s]", GeneratedHttpRequest.class.cast(request).getDeclaring()
diff --git a/core/src/main/java/org/jclouds/http/functions/ParseXMLWithJAXB.java b/core/src/main/java/org/jclouds/http/functions/ParseXMLWithJAXB.java
index 2b7e5e8..2ed2f23 100644
--- a/core/src/main/java/org/jclouds/http/functions/ParseXMLWithJAXB.java
+++ b/core/src/main/java/org/jclouds/http/functions/ParseXMLWithJAXB.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.http.functions;
import static org.jclouds.http.HttpUtils.releasePayload;
diff --git a/core/src/main/java/org/jclouds/javax/annotation/Nullable.java b/core/src/main/java/org/jclouds/javax/annotation/Nullable.java
index d75f256..37d9acf 100644
--- a/core/src/main/java/org/jclouds/javax/annotation/Nullable.java
+++ b/core/src/main/java/org/jclouds/javax/annotation/Nullable.java
@@ -1,3 +1,21 @@
+/**
+ * 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.javax.annotation;
@java.lang.annotation.Documented
diff --git a/core/src/main/java/org/jclouds/javax/annotation/concurrent/NotThreadSafe.java b/core/src/main/java/org/jclouds/javax/annotation/concurrent/NotThreadSafe.java
index 47a4b15..b51ac76 100644
--- a/core/src/main/java/org/jclouds/javax/annotation/concurrent/NotThreadSafe.java
+++ b/core/src/main/java/org/jclouds/javax/annotation/concurrent/NotThreadSafe.java
@@ -1,3 +1,21 @@
+/**
+ * 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.javax.annotation.concurrent;
@java.lang.annotation.Documented
diff --git a/core/src/main/java/org/jclouds/json/config/GsonModule.java b/core/src/main/java/org/jclouds/json/config/GsonModule.java
index aaece5b..5087037 100644
--- a/core/src/main/java/org/jclouds/json/config/GsonModule.java
+++ b/core/src/main/java/org/jclouds/json/config/GsonModule.java
@@ -27,6 +27,7 @@
import java.util.Properties;
import javax.inject.Inject;
+import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.crypto.CryptoStreams;
@@ -35,20 +36,14 @@
import org.jclouds.json.Json;
import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
import org.jclouds.json.internal.GsonWrapper;
-import org.jclouds.json.internal.JsonLiteral;
+import org.jclouds.json.internal.NullHackJsonLiteralAdapter;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Maps;
+import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.primitives.Bytes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
import com.google.gson.TypeAdapter;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.reflect.TypeToken;
@@ -57,7 +52,6 @@
import com.google.inject.AbstractModule;
import com.google.inject.ImplementedBy;
import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
/**
* Contains logic for parsing objects from Strings.
@@ -69,9 +63,9 @@
@SuppressWarnings("rawtypes")
@Provides
@Singleton
- Gson provideGson(JsonBallAdapter jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
- ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings)
- throws ClassNotFoundException, Exception {
+ Gson provideGson(TypeAdapter<JsonBall> jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
+ ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings)
+ throws ClassNotFoundException, Exception {
GsonBuilder builder = new GsonBuilder();
// simple (type adapters)
@@ -80,43 +74,38 @@
builder.registerTypeAdapter(new TypeToken<List<Byte>>() {
}.getType(), byteListAdapter.nullSafe());
builder.registerTypeAdapter(byte[].class, byteArrayAdapter.nullSafe());
+ builder.registerTypeAdapter(JsonBall.class, jsonAdapter.nullSafe());
// complicated (serializers/deserializers as they need context to operate)
builder.registerTypeHierarchyAdapter(Enum.class, new EnumTypeAdapterThatReturnsFromValue());
- builder.registerTypeAdapter(JsonBall.class, jsonAdapter);
for (Map.Entry<Type, Object> binding : bindings.getBindings().entrySet()) {
builder.registerTypeAdapter(binding.getKey(), binding.getValue());
}
-
+
return builder.create();
}
- // http://code.google.com/p/google-gson/issues/detail?id=326
- @ImplementedBy(JsonBallAdapterImpl.class)
- public static interface JsonBallAdapter extends JsonSerializer<JsonBall>, JsonDeserializer<JsonBall> {
-
- }
-
- @Singleton
- public static class JsonBallAdapterImpl implements JsonBallAdapter {
-
- public JsonElement serialize(JsonBall src, Type typeOfSrc, JsonSerializationContext context) {
- return new JsonLiteral(src);
- }
-
- public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- return new JsonBall(json.toString());
- }
-
- }
-
@ImplementedBy(CDateAdapter.class)
public static abstract class DateAdapter extends TypeAdapter<Date> {
}
+ @Provides
+ @Singleton
+ protected TypeAdapter<JsonBall> provideJsonBallAdapter(NullHackJsonBallAdapter in) {
+ return in;
+ }
+
+ public static class NullHackJsonBallAdapter extends NullHackJsonLiteralAdapter<JsonBall> {
+
+ @Override
+ protected JsonBall createJsonLiteralFromRawJson(String json) {
+ return new JsonBall(json);
+ }
+
+ }
+
@ImplementedBy(HexByteListAdapter.class)
public static abstract class ByteListAdapter extends TypeAdapter<List<Byte>> {
@@ -185,15 +174,15 @@
@Singleton
public static class PropertiesAdapter extends TypeAdapter<Properties> {
- private final Json json;
- private final Type mapType = new TypeLiteral<Map<String, String>>() {
- }.getRawType();
+ private final Provider<Gson> gson;
+ private final TypeToken<Map<String, String>> mapType = new TypeToken<Map<String, String>>() {
+ };
@Inject
- public PropertiesAdapter(Json json) {
- this.json = json;
+ public PropertiesAdapter(Provider<Gson> gson) {
+ this.gson = gson;
}
-
+
@Override
public void write(JsonWriter out, Properties value) throws IOException {
Builder<String, String> srcMap = ImmutableMap.<String, String> builder();
@@ -201,7 +190,7 @@
String propName = (String) propNames.nextElement();
srcMap.put(propName, value.getProperty(propName));
}
- out.value(new JsonLiteral(json.toJson(srcMap.build(), mapType)));
+ gson.get().getAdapter(mapType).write(out, srcMap.build());
}
@Override
@@ -209,8 +198,8 @@
Properties props = new Properties();
in.beginObject();
while (in.hasNext()) {
- JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
- props.setProperty(in.nextString(), in.nextString());
+ JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
+ props.setProperty(in.nextString(), in.nextString());
}
in.endObject();
return props;
diff --git a/core/src/main/java/org/jclouds/json/internal/JsonLiteral.java b/core/src/main/java/org/jclouds/json/internal/JsonLiteral.java
deleted file mode 100644
index 6fee782..0000000
--- a/core/src/main/java/org/jclouds/json/internal/JsonLiteral.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * 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.json.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.gson.JsonElement;
-
-/**
- * The gson project use package to control access to their objects. However, this prevents us from
- * doing valid work, like controlling the json emitted on a per-object basis. This is here to afford
- * us to do this.
- *
- * @author Adrian Cole
- * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
- */
-public final class JsonLiteral extends JsonElement {
- private final CharSequence literal;
-
- public JsonLiteral(CharSequence literal) {
- this.literal = checkNotNull(literal, "literal");
- }
-
- @Override
- public String toString() {
- return literal.toString();
- }
-
-}
diff --git a/core/src/main/java/org/jclouds/json/internal/NullHackJsonLiteralAdapter.java b/core/src/main/java/org/jclouds/json/internal/NullHackJsonLiteralAdapter.java
new file mode 100644
index 0000000..6efba01
--- /dev/null
+++ b/core/src/main/java/org/jclouds/json/internal/NullHackJsonLiteralAdapter.java
@@ -0,0 +1,135 @@
+/**
+ * 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.json.internal;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.Field;
+
+import javax.inject.Singleton;
+
+import com.google.common.base.Throwables;
+import com.google.gson.TypeAdapter;
+import com.google.gson.internal.bind.TypeAdapters;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * writes or reads the literal json directly
+ *
+ * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326" />
+ *
+ */
+@Singleton
+public abstract class NullHackJsonLiteralAdapter<L> extends TypeAdapter<L> {
+
+ @Override
+ public L read(JsonReader reader) throws IOException {
+ return createJsonLiteralFromRawJson(TypeAdapters.JSON_ELEMENT.read(reader).toString());
+ }
+
+
+ /**
+ * User supplied type that holds json literally. Ex. number as {@code 8}, boolean as {@code true}
+ * , string as {@code "value"}, object as {@code , list {@code []}.
+ */
+ protected abstract L createJsonLiteralFromRawJson(String json);
+
+ // the writer inside JsonWriter is not accessible currently
+ private static final Field outField;
+ static {
+ try {
+ outField = JsonWriter.class.getDeclaredField("out");
+ } catch (SecurityException e) {
+ throw Throwables.propagate(e);
+ } catch (NoSuchFieldException e) {
+ throw Throwables.propagate(e);
+ }
+ outField.setAccessible(true);
+ }
+
+ @Override
+ public void write(JsonWriter jsonWriter, L value) throws IOException {
+
+ Writer writer = getWriter(jsonWriter);
+ boolean serializeNulls = jsonWriter.getSerializeNulls();
+ try {
+ // we are using an implementation hack which depends on replacing null with the raw json
+ // supplied as a parameter. In this case, we must ensure we indeed serialize nulls.
+ NullReplacingWriter nullReplacingWriter = new NullReplacingWriter(writer, value.toString());
+ setWriter(jsonWriter, nullReplacingWriter);
+ jsonWriter.setSerializeNulls(true);
+ jsonWriter.nullValue();
+ } finally {
+ setWriter(jsonWriter, writer);
+ jsonWriter.setSerializeNulls(serializeNulls);
+ }
+
+ }
+
+ private Writer getWriter(JsonWriter arg0) {
+ try {
+ return Writer.class.cast(outField.get(arg0));
+ } catch (IllegalAccessException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private void setWriter(JsonWriter arg0, Writer arg1) {
+ try {
+ outField.set(arg0, arg1);
+ } catch (IllegalAccessException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private final class NullReplacingWriter extends Writer {
+ private final Writer delegate;
+ private final String nullReplacement;
+
+ public NullReplacingWriter(Writer delegate, String nullReplacement) {
+ this.delegate = delegate;
+ this.nullReplacement = nullReplacement;
+ }
+
+ @Override
+ public void write(char[] buffer, int offset, int count) throws IOException {
+ delegate.write(buffer, offset, count);
+ }
+
+ @Override
+ public void write(String s) throws IOException {
+ if (nullReplacement != null && s.equals("null")) {
+ s = nullReplacement;
+ }
+ super.write(s);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ delegate.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ delegate.close();
+ }
+
+ }
+}
diff --git a/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java b/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java
index 39b3220..6f5e85c 100644
--- a/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java
+++ b/core/src/main/java/org/jclouds/lifecycle/config/LifeCycleModule.java
@@ -35,10 +35,13 @@
import javax.inject.Named;
import org.jclouds.Constants;
+import org.jclouds.concurrent.MoreExecutors;
import org.jclouds.lifecycle.Closer;
+import com.google.common.base.Throwables;
+import com.google.common.util.concurrent.ExecutionList;
import com.google.inject.AbstractModule;
-import com.google.inject.ProvisionException;
+import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.TypeEncounter;
@@ -49,6 +52,15 @@
* {@link PostConstruct} after injection, and Associate {@link PreDestroy} with a global
* {@link Closer} object.
*
+ * <h3>Important</h3> Make sure you create your injector with {@link Stage#PRODUCTION} and execute
+ * the bound {@link ExecutionList} prior to using any other objects.
+ *
+ * <p/>
+ * Ex.
+ * <pre>
+ *
+ * </pre>
+ *
* @author Adrian Cole
*/
public class LifeCycleModule extends AbstractModule {
@@ -75,10 +87,13 @@
Closer closer = new Closer();
closer.addToClose(executorCloser);
bind(Closer.class).toInstance(closer);
- bindPostInjectionInvoke(closer);
+
+ ExecutionList list = new ExecutionList();
+ bindPostInjectionInvoke(closer, list);
+ bind(ExecutionList.class).toInstance(list);
}
- protected void bindPostInjectionInvoke(final Closer closer) {
+ protected void bindPostInjectionInvoke(final Closer closer, final ExecutionList list) {
bindListener(any(), new TypeListener() {
public <I> void hear(TypeLiteral<I> injectableType, TypeEncounter<I> encounter) {
Set<Method> methods = new HashSet<Method>();
@@ -93,8 +108,8 @@
}
}
- private <I> void associatePreDestroyWithCloser(final Closer closer,
- TypeEncounter<I> encounter, final Method method) {
+ private <I> void associatePreDestroyWithCloser(final Closer closer, TypeEncounter<I> encounter,
+ final Method method) {
PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
if (preDestroy != null) {
encounter.register(new InjectionListener<I>() {
@@ -117,20 +132,23 @@
}
}
- private <I> void invokePostConstructMethodAfterInjection(TypeEncounter<I> encounter,
- final Method method) {
+ private <I> void invokePostConstructMethodAfterInjection(TypeEncounter<I> encounter, final Method method) {
PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
if (postConstruct != null) {
encounter.register(new InjectionListener<I>() {
- public void afterInjection(I injectee) {
- try {
- method.invoke(injectee);
- } catch (InvocationTargetException ie) {
- Throwable e = ie.getTargetException();
- throw new ProvisionException(e.getMessage(), e);
- } catch (IllegalAccessException e) {
- throw new ProvisionException(e.getMessage(), e);
- }
+ public void afterInjection(final I injectee) {
+ list.add(new Runnable() {
+ public void run() {
+ try {
+ method.invoke(injectee);
+ } catch (InvocationTargetException ie) {
+ Throwable e = ie.getTargetException();
+ throw Throwables.propagate(e);
+ } catch (IllegalAccessException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+ }, MoreExecutors.sameThreadExecutor());
}
});
}
diff --git a/core/src/main/java/org/jclouds/location/config/LocationModule.java b/core/src/main/java/org/jclouds/location/config/LocationModule.java
index 63f8cd8..8465d76 100644
--- a/core/src/main/java/org/jclouds/location/config/LocationModule.java
+++ b/core/src/main/java/org/jclouds/location/config/LocationModule.java
@@ -20,7 +20,6 @@
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -32,10 +31,7 @@
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
-import com.google.common.base.Function;
import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -56,27 +52,6 @@
@Provides
@Singleton
- protected Supplier<Map<String, ? extends Location>> provideLocationMap(
- @Memoized Supplier<Set<? extends Location>> locations) {
- return Suppliers.compose(new Function<Set<? extends Location>, Map<String, ? extends Location>>() {
-
- @Override
- public Map<String, ? extends Location> apply(Set<? extends Location> from) {
- return Maps.uniqueIndex(from, new Function<Location, String>() {
-
- @Override
- public String apply(Location from) {
- return from.getId();
- }
-
- });
- }
-
- }, locations);
- }
-
- @Provides
- @Singleton
@Memoized
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Location>> locationSupplier) {
diff --git a/core/src/main/java/org/jclouds/location/predicates/LocationPredicates.java b/core/src/main/java/org/jclouds/location/predicates/LocationPredicates.java
index f56ca86..73e4722 100644
--- a/core/src/main/java/org/jclouds/location/predicates/LocationPredicates.java
+++ b/core/src/main/java/org/jclouds/location/predicates/LocationPredicates.java
@@ -68,6 +68,30 @@
}
}
+ public static Predicate<Location> idEquals(String id) {
+ return new IdEquals(id);
+ }
+
+ static class IdEquals implements Predicate<Location> {
+
+ private final String id;
+
+ IdEquals(String id) {
+ this.id = checkNotNull(id, "id");
+ }
+
+ @Override
+ public boolean apply(Location input) {
+
+ return input.getId().equals(id);
+ }
+
+ @Override
+ public String toString() {
+ return "idEquals(" + id + ")";
+ }
+ }
+
public static Predicate<Location> isZoneOrRegionWhereRegionIdEquals(String region) {
return new IsZoneOrRegionWhereRegionIdEquals(region);
}
diff --git a/core/src/main/java/org/jclouds/rest/RestContext.java b/core/src/main/java/org/jclouds/rest/RestContext.java
index c07ab1c..c03665d 100644
--- a/core/src/main/java/org/jclouds/rest/RestContext.java
+++ b/core/src/main/java/org/jclouds/rest/RestContext.java
@@ -22,6 +22,7 @@
import java.util.Map;
import java.util.concurrent.Future;
+import org.jclouds.Constants;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.rest.internal.RestContextImpl;
@@ -58,9 +59,19 @@
S getApi();
URI getEndpoint();
-
+
+ /**
+ * @return version of the api presented by this service
+ * @see Constants#PROPERTY_API_VERSION
+ */
String getApiVersion();
+ /**
+ * @return version of software this service is running
+ * @see Constants#PROPERTY_BUILD_VERSION
+ */
+ String getBuildVersion();
+
String getIdentity();
/**
diff --git a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java
index 94894c6..e60d9bd 100644
--- a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java
+++ b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java
@@ -31,6 +31,7 @@
import static com.google.inject.util.Types.newParameterizedType;
import static org.jclouds.Constants.PROPERTY_API;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
+import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
@@ -39,14 +40,17 @@
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
import java.net.URI;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
import java.util.Map.Entry;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
-import com.google.common.collect.*;
import org.jclouds.concurrent.MoreExecutors;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
@@ -54,6 +58,7 @@
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
+import org.jclouds.lifecycle.config.LifeCycleModule;
import org.jclouds.location.Iso3166;
import org.jclouds.location.Provider;
import org.jclouds.location.config.ProvideIso3166CodesByLocationIdViaProperties;
@@ -61,6 +66,7 @@
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rest.annotations.Api;
import org.jclouds.rest.annotations.ApiVersion;
+import org.jclouds.rest.annotations.BuildVersion;
import org.jclouds.rest.annotations.Credential;
import org.jclouds.rest.annotations.Identity;
import org.jclouds.rest.config.CredentialStoreModule;
@@ -70,12 +76,19 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ExecutionList;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
+import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
/**
@@ -149,6 +162,8 @@
bind(String.class).annotatedWith(Api.class).toInstance(toBind.getProperty(PROPERTY_API));
if (toBind.containsKey(PROPERTY_API_VERSION))
bind(String.class).annotatedWith(ApiVersion.class).toInstance(toBind.getProperty(PROPERTY_API_VERSION));
+ if (toBind.containsKey(PROPERTY_BUILD_VERSION))
+ bind(String.class).annotatedWith(BuildVersion.class).toInstance(toBind.getProperty(PROPERTY_BUILD_VERSION));
if (toBind.containsKey(PROPERTY_IDENTITY))
bind(String.class).annotatedWith(Identity.class).toInstance(
checkNotNull(toBind.getProperty(PROPERTY_IDENTITY), PROPERTY_IDENTITY));
@@ -182,8 +197,11 @@
ifHttpConfigureRestOtherwiseGuiceClientFactory(modules);
addExecutorServiceIfNotPresent(modules);
addCredentialStoreIfNotPresent(modules);
+ modules.add(new LifeCycleModule());
modules.add(new BindPropertiesAndPrincipalContext(properties));
- return Guice.createInjector(modules);
+ Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules);
+ returnVal.getInstance(ExecutionList.class).execute();
+ return returnVal;
}
@VisibleForTesting
diff --git a/core/src/main/java/org/jclouds/rest/RestContextFactory.java b/core/src/main/java/org/jclouds/rest/RestContextFactory.java
index bc88244..4aacd74 100644
--- a/core/src/main/java/org/jclouds/rest/RestContextFactory.java
+++ b/core/src/main/java/org/jclouds/rest/RestContextFactory.java
@@ -30,10 +30,10 @@
import java.io.IOException;
import java.util.Properties;
-import org.jclouds.javax.annotation.Nullable;
import javax.inject.Inject;
import org.jclouds.PropertiesBuilder;
+import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.reference.LocationConstants;
import org.jclouds.util.ClassLoadingUtils;
import org.jclouds.util.Modules2;
@@ -72,24 +72,24 @@
public class RestContextFactory {
public static <S, A> RestContextSpec<S, A> contextSpec(String provider, String endpoint, String apiVersion,
- String iso3166Codes, String identity, String credential, Class<S> sync, Class<A> async,
+ String buildVersion, String iso3166Codes, String identity, String credential, Class<S> sync, Class<A> async,
Class<PropertiesBuilder> propertiesBuilderClass, Class<RestContextBuilder<S, A>> contextBuilderClass,
Iterable<Module> modules) {
- return new RestContextSpec<S, A>(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async,
- propertiesBuilderClass, contextBuilderClass, modules);
+ return new RestContextSpec<S, A>(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity,
+ credential, sync, async, propertiesBuilderClass, contextBuilderClass, modules);
}
- public static <S, A> RestContextSpec<S, A> contextSpec(String provider, String endpoint, String apiVersion,
+ public static <S, A> RestContextSpec<S, A> contextSpec(String provider, String endpoint, String apiVersion,String buildVersion,
String iso3166Codes, String identity, String credential, Class<S> sync, Class<A> async) {
- return new RestContextSpec<S, A>(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async);
+ return new RestContextSpec<S, A>(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, sync, async);
}
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings( { "unchecked", "rawtypes" })
public static <S, A> RestContextSpec<S, A> contextSpec(String provider, String endpoint, String apiVersion,
- String iso3166Codes, String identity, String credential, Class<S> sync, Class<A> async,
- Iterable<Module> modules) {
- return new RestContextSpec<S, A>(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async,
- PropertiesBuilder.class, (Class) RestContextBuilder.class, modules);
+ String buildVersion, String iso3166Codes, String identity, String credential, Class<S> sync,
+ Class<A> async, Iterable<Module> modules) {
+ return new RestContextSpec<S, A>(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity,
+ credential, sync, async, PropertiesBuilder.class, (Class) RestContextBuilder.class, modules);
}
private final static Properties NO_PROPERTIES = new Properties();
@@ -241,7 +241,8 @@
Properties props = new Properties();
props.setProperty(contextSpec.provider + ".endpoint", contextSpec.endpoint);
- props.setProperty(contextSpec.provider + ".apiversion", contextSpec.apiVersion);
+ props.setProperty(contextSpec.provider + ".api-version", contextSpec.apiVersion);
+ props.setProperty(contextSpec.provider + ".build-version", contextSpec.buildVersion);
props.setProperty(contextSpec.provider + "." + LocationConstants.ISO3166_CODES, contextSpec.iso3166Codes);
props.setProperty(contextSpec.provider + ".identity", contextSpec.identity);
if (contextSpec.credential != null)
@@ -289,7 +290,8 @@
String endpoint = props.getProperty(providerName + "." + LocationConstants.ENDPOINT, null);
String iso3166Codes = props.getProperty(providerName + "." + LocationConstants.ISO3166_CODES, null);
- String apiVersion = props.getProperty(providerName + ".apiversion", null);
+ String apiVersion = props.getProperty(providerName + ".api-version", null);
+ String buildVersion = props.getProperty(providerName + ".build-version", null);
identity = props.getProperty(providerName + ".identity", props.getProperty("jclouds.identity", identity));
credential = loadCredentialOrDefault(props, providerName + ".credential",
loadCredentialOrDefault(props, "jclouds.credential", credential));
@@ -316,7 +318,7 @@
assert false : "exception should have propogated " + e;
return null;
}
- RestContextSpec<S, A> contextSpec = new RestContextSpec<S, A>(providerName, endpoint, apiVersion, iso3166Codes,
+ RestContextSpec<S, A> contextSpec = new RestContextSpec<S, A>(providerName, endpoint, apiVersion, buildVersion, iso3166Codes,
identity, credential, sync, async, propertiesBuilderClass, contextBuilderClass, modules);
return contextSpec;
}
@@ -365,6 +367,8 @@
builder.provider(contextSpec.provider);
if (contextSpec.apiVersion != null)
builder.apiVersion(contextSpec.apiVersion);
+ if (contextSpec.buildVersion != null)
+ builder.buildVersion(contextSpec.buildVersion);
if (contextSpec.iso3166Codes != null)
builder.iso3166Codes(Splitter.on('.').split(contextSpec.iso3166Codes));
if (contextSpec.identity != null)
diff --git a/core/src/main/java/org/jclouds/rest/RestContextSpec.java b/core/src/main/java/org/jclouds/rest/RestContextSpec.java
index a1a4cef..9cbea95 100644
--- a/core/src/main/java/org/jclouds/rest/RestContextSpec.java
+++ b/core/src/main/java/org/jclouds/rest/RestContextSpec.java
@@ -35,6 +35,7 @@
protected final String provider;
protected final String endpoint;
protected final String apiVersion;
+ protected final String buildVersion;
protected final String iso3166Codes;
protected final String identity;
protected final String credential;
@@ -44,12 +45,13 @@
protected final Class<RestContextBuilder<S, A>> contextBuilderClass;
protected final Iterable<Module> modules;
- public RestContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, String identity,
+ public RestContextSpec(String provider, String endpoint, String apiVersion, String buildVersion, String iso3166Codes, String identity,
String credential, Class<S> sync, Class<A> async, Class<PropertiesBuilder> propertiesBuilderClass,
Class<RestContextBuilder<S, A>> contextBuilderClass, Iterable<Module> modules) {
this.provider = checkNotNull(provider, "provider");
this.endpoint = endpoint;
this.apiVersion = apiVersion;
+ this.buildVersion = buildVersion;
this.identity = identity;
this.credential = credential;
this.iso3166Codes = iso3166Codes;
@@ -65,26 +67,19 @@
}
@SuppressWarnings( { "unchecked", "rawtypes" })
- public RestContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, String identity,
+ public RestContextSpec(String provider, String endpoint, String apiVersion, String buildVersion, String iso3166Codes, String identity,
String credential, Class<S> sync, Class<A> async) {
- this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async, PropertiesBuilder.class,
+ this(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, sync, async, PropertiesBuilder.class,
(Class) RestContextBuilder.class, EMPTY_LIST);
}
- /**
- * this uses the inefficient {@link Objects} implementation as the object count will be
- * relatively small and therefore efficiency is not a concern.
- */
+
@Override
public int hashCode() {
- return Objects.hashCode(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async,
+ return Objects.hashCode(provider, endpoint, apiVersion, buildVersion, iso3166Codes, identity, credential, sync, async,
propertiesBuilderClass, contextBuilderClass, modules);
}
- /**
- * this uses the inefficient {@link Objects} implementation as the object count will be
- * relatively small and therefore efficiency is not a concern.
- */
@Override
public boolean equals(Object that) {
if (that == null)
@@ -92,16 +87,13 @@
return Objects.equal(this.toString(), that.toString());
}
- /**
- * this uses the inefficient {@link Objects} implementation as the object count will be
- * relatively small and therefore efficiency is not a concern.
- */
@Override
public String toString() {
return Objects.toStringHelper(this).add("provider", provider).add("endpoint", endpoint).add("apiVersion",
- apiVersion).add("iso3166Codes", iso3166Codes).add("identity", identity).add("sync", sync).add("async",
- async).add("propertiesBuilderClass", propertiesBuilderClass).add("contextBuilderClass",
- contextBuilderClass).add("modules", modules).toString();
+ apiVersion).add("buildVersion", buildVersion).add("iso3166Codes", iso3166Codes)
+ .add("identity", identity).add("sync", sync).add("async", async).add("propertiesBuilderClass",
+ propertiesBuilderClass).add("contextBuilderClass", contextBuilderClass).add("modules", modules)
+ .toString();
}
}
\ No newline at end of file
diff --git a/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java b/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java
index 6f2aab0..210a598 100644
--- a/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java
+++ b/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java
@@ -28,10 +28,13 @@
import javax.inject.Qualifier;
+import org.jclouds.Constants;
+
/**
* Designates that this Resource qualifies an object to an api version.
*
* @author Adrian Cole
+ * @see Constants#PROPERTY_API_VERSION
*/
@Target( { ANNOTATION_TYPE, FIELD, PARAMETER })
@Retention(RUNTIME)
diff --git a/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java b/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java
new file mode 100644
index 0000000..3586a3c
--- /dev/null
+++ b/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java
@@ -0,0 +1,44 @@
+/**
+ * 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.rest.annotations;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+import org.jclouds.Constants;
+
+/**
+ * Designates that this Resource qualifies an object to an build version.
+ *
+ * @author Adrian Cole
+ * @see Constants#PROPERTY_BUILD_VERSION
+ */
+@Target( { ANNOTATION_TYPE, FIELD, PARAMETER })
+@Retention(RUNTIME)
+@Qualifier
+public @interface BuildVersion {
+
+}
diff --git a/core/src/main/java/org/jclouds/rest/binders/BindException.java b/core/src/main/java/org/jclouds/rest/binders/BindException.java
index fe2fcbf..6e52cd2 100644
--- a/core/src/main/java/org/jclouds/rest/binders/BindException.java
+++ b/core/src/main/java/org/jclouds/rest/binders/BindException.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.rest.binders;
import org.jclouds.http.HttpRequest;
diff --git a/core/src/main/java/org/jclouds/rest/binders/BindToXMLPayload.java b/core/src/main/java/org/jclouds/rest/binders/BindToXMLPayload.java
index 6adfecb..87a31fe 100644
--- a/core/src/main/java/org/jclouds/rest/binders/BindToXMLPayload.java
+++ b/core/src/main/java/org/jclouds/rest/binders/BindToXMLPayload.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.rest.binders;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/core/src/main/java/org/jclouds/rest/config/RestClientModule.java b/core/src/main/java/org/jclouds/rest/config/RestClientModule.java
index 3041976..c6c56e6 100644
--- a/core/src/main/java/org/jclouds/rest/config/RestClientModule.java
+++ b/core/src/main/java/org/jclouds/rest/config/RestClientModule.java
@@ -29,8 +29,8 @@
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.RestContextImpl;
-import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -71,6 +71,9 @@
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(
RestContextImpl.class, syncClientType, asyncClientType))).in(
Scopes.SINGLETON);
+ bind(TypeLiteral.get(Types.newParameterizedType(RestContext.class, syncClientType, asyncClientType))).to(
+ (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, syncClientType,
+ asyncClientType))).in(Scopes.SINGLETON);
bindAsyncClient();
bindClient();
bindErrorHandlers();
diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
index 4b2133d..1a26d26 100644
--- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
+++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
@@ -47,13 +47,12 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
+import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
-import javax.inject.Named;
import javax.inject.Provider;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
@@ -78,7 +77,6 @@
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x;
import org.jclouds.http.functions.ParseXMLWithJAXB;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
@@ -86,6 +84,7 @@
import org.jclouds.http.functions.ReturnStringIf2xx;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.http.functions.UnwrapOnlyJsonValue;
+import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.internal.ClassMethodArgs;
@@ -102,7 +101,9 @@
import org.jclouds.rest.Binder;
import org.jclouds.rest.InputParamValidator;
import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.BuildVersion;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
@@ -145,12 +146,12 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -245,6 +246,7 @@
private final Provider<UriBuilder> uriBuilderProvider;
private final LoadingCache<Class<?>, Boolean> seedAnnotationCache;
private final String apiVersion;
+ private final String buildVersion;
private char[] skips;
@Inject
@@ -306,8 +308,8 @@
@SuppressWarnings("unchecked")
@Inject
public RestAnnotationProcessor(Injector injector, LoadingCache<Class<?>, Boolean> seedAnnotationCache,
- @Named(Constants.PROPERTY_API_VERSION) String apiVersion, ParseSax.Factory parserFactory, HttpUtils utils,
- TypeLiteral<T> typeLiteral) throws ExecutionException {
+ @ApiVersion String apiVersion, @BuildVersion String buildVersion, ParseSax.Factory parserFactory,
+ HttpUtils utils, TypeLiteral<T> typeLiteral) throws ExecutionException {
this.declaring = (Class<T>) typeLiteral.getRawType();
this.injector = injector;
this.parserFactory = parserFactory;
@@ -321,6 +323,7 @@
skips = new char[] {};
}
this.apiVersion = apiVersion;
+ this.buildVersion = buildVersion;
}
public Method getDelegateOrNull(Method in) {
@@ -435,6 +438,7 @@
Multimap<String, String> tokenValues = LinkedHashMultimap.create();
tokenValues.put(Constants.PROPERTY_API_VERSION, apiVersion);
+ tokenValues.put(Constants.PROPERTY_BUILD_VERSION, buildVersion);
tokenValues.putAll(addPathAndGetTokens(declaring, method, args, builder));
diff --git a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java
index 2a83936..5c8f2f3 100644
--- a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java
+++ b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java
@@ -36,8 +36,10 @@
import org.jclouds.rest.RestContext;
import org.jclouds.rest.Utils;
import org.jclouds.rest.annotations.ApiVersion;
+import org.jclouds.rest.annotations.BuildVersion;
import org.jclouds.rest.annotations.Identity;
+import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Key;
@@ -59,6 +61,7 @@
private final String identity;
private final String provider;
private final String apiVersion;
+ private final String buildVersion;
private final Utils utils;
private final Map<String, Credentials> credentialStore;
private final Set<String> iso3166Codes;
@@ -66,7 +69,8 @@
@Inject
protected RestContextImpl(Closer closer, Map<String, Credentials> credentialStore, Utils utils, Injector injector,
TypeLiteral<S> syncApi, TypeLiteral<A> asyncApi, @Provider URI endpoint, @Provider String provider,
- @Identity String identity, @ApiVersion String apiVersion, @Iso3166 Set<String> iso3166Codes) {
+ @Identity String identity, @ApiVersion String apiVersion, @BuildVersion String buildVersion,
+ @Iso3166 Set<String> iso3166Codes) {
this.credentialStore = credentialStore;
this.utils = utils;
this.asyncApi = injector.getInstance(Key.get(asyncApi));
@@ -76,6 +80,7 @@
this.identity = identity;
this.provider = provider;
this.apiVersion = apiVersion;
+ this.buildVersion = buildVersion;
this.iso3166Codes = iso3166Codes;
}
@@ -127,16 +132,16 @@
public String getApiVersion() {
return apiVersion;
}
+
+ @Override
+ public String getBuildVersion() {
+ return buildVersion;
+ }
+
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((apiVersion == null) ? 0 : apiVersion.hashCode());
- result = prime * result + ((endpoint == null) ? 0 : endpoint.hashCode());
- result = prime * result + ((identity == null) ? 0 : identity.hashCode());
- result = prime * result + ((provider == null) ? 0 : provider.hashCode());
- return result;
+ return Objects.hashCode(provider, endpoint, apiVersion, buildVersion, identity);
}
@Override
@@ -147,34 +152,17 @@
return false;
if (getClass() != obj.getClass())
return false;
- RestContextImpl<?, ?> other = (RestContextImpl<?, ?>) obj;
- if (apiVersion == null) {
- if (other.apiVersion != null)
- return false;
- } else if (!apiVersion.equals(other.apiVersion))
- return false;
- if (endpoint == null) {
- if (other.endpoint != null)
- return false;
- } else if (!endpoint.equals(other.endpoint))
- return false;
- if (identity == null) {
- if (other.identity != null)
- return false;
- } else if (!identity.equals(other.identity))
- return false;
- if (provider == null) {
- if (other.provider != null)
- return false;
- } else if (!provider.equals(other.provider))
- return false;
- return true;
+ RestContextImpl<?, ?> that = (RestContextImpl<?, ?>) obj;
+ return Objects.equal(this.provider, that.provider) && Objects.equal(this.endpoint, that.endpoint)
+ && Objects.equal(this.apiVersion, that.apiVersion)
+ && Objects.equal(this.buildVersion, that.buildVersion) && Objects.equal(this.identity, that.identity);
}
@Override
public String toString() {
- return " [id=" + provider + ", endpoint=" + endpoint + ", apiVersion=" + apiVersion + ", identity=" + identity
- + ", iso3166Codes=" + iso3166Codes + "]";
+ return Objects.toStringHelper("").add("provider", provider).add("endpoint", endpoint).add("apiVersion",
+ apiVersion).add("buildVersion", buildVersion).add("identity", identity)
+ .add("iso3166Codes", iso3166Codes).toString();
}
@Override
@@ -204,7 +192,8 @@
@Override
public Map<String, Object> getMetadata() {
- return ImmutableMap.<String, Object> of("endpoint", endpoint, "apiVersion", apiVersion, "identity", identity);
+ return ImmutableMap.<String, Object> of("endpoint", endpoint, "apiVersion", apiVersion, "buildVersion",
+ buildVersion, "identity", identity);
}
@Override
diff --git a/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java b/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java
index 3c7de37..6fa91df 100644
--- a/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java
+++ b/core/src/main/java/org/jclouds/rest/suppliers/MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.java
@@ -18,7 +18,7 @@
*/
package org.jclouds.rest.suppliers;
-import static com.google.common.base.Suppliers.memoizeWithExpiration;
+import static org.jclouds.util.Suppliers2.memoizeWithExpirationOnAbsoluteInterval;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -49,7 +49,7 @@
public MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
- this.delegate = memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<T>(
+ this.delegate = memoizeWithExpirationOnAbsoluteInterval(new RetryOnTimeOutExceptionSupplier<T>(
new SetAndThrowAuthorizationExceptionSupplier<T>(delegate, authException)), seconds, TimeUnit.SECONDS);
this.seconds = seconds;
}
diff --git a/core/src/main/java/org/jclouds/util/Patterns.java b/core/src/main/java/org/jclouds/util/Patterns.java
index b0b5052..2e9a38d 100644
--- a/core/src/main/java/org/jclouds/util/Patterns.java
+++ b/core/src/main/java/org/jclouds/util/Patterns.java
@@ -39,6 +39,7 @@
public static final Pattern PATTERN_THAT_BREAKS_URI = Pattern.compile("[a-z0-9]+://.*/.*@.*");
public static final Pattern JSON_STRING_PATTERN = Pattern.compile("^[^\"\\{\\[].*[^\\{\\[\"]$");
public static final Pattern JSON_NUMBER_PATTERN = Pattern.compile("^[0-9]*\\.?[0-9]*$");
+ public static final Pattern JSON_BOOLEAN_PATTERN = Pattern.compile("^(true|false)$");
public static final Pattern PLUS_PATTERN = Pattern.compile("\\+");
public static final Pattern STAR_PATTERN = Pattern.compile("\\*");
public static final Pattern _7E_PATTERN = Pattern.compile("%7E");
diff --git a/core/src/main/java/org/jclouds/util/Suppliers2.java b/core/src/main/java/org/jclouds/util/Suppliers2.java
index 0df90ab..bbfa6a1 100644
--- a/core/src/main/java/org/jclouds/util/Suppliers2.java
+++ b/core/src/main/java/org/jclouds/util/Suppliers2.java
@@ -22,7 +22,12 @@
import java.io.IOException;
import java.io.OutputStream;
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Supplier;
import com.google.common.io.OutputSupplier;
/**
@@ -44,5 +49,63 @@
};
}
-
+ /**
+ * See Supplier.memoizeWithExpiration.
+ *
+ * Difference between this impl and v11.0 is that we fix http://code.google.com/p/guava-libraries/issues/detail?id=857.
+ */
+ public static <T> Supplier<T> memoizeWithExpirationOnAbsoluteInterval(Supplier<T> delegate, long duration, TimeUnit unit) {
+ return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
+ }
+
+ @VisibleForTesting
+ static class ExpiringMemoizingSupplier<T> implements Supplier<T>, Serializable {
+ final Supplier<T> delegate;
+ final long durationNanos;
+ transient volatile T value;
+ // The special value 0 means "not yet initialized".
+ transient volatile long expirationNanos;
+
+ ExpiringMemoizingSupplier(Supplier<T> delegate, long duration, TimeUnit unit) {
+ this.delegate = Preconditions.checkNotNull(delegate);
+ this.durationNanos = unit.toNanos(duration);
+ Preconditions.checkArgument(duration > 0);
+ }
+
+ @Override
+ public T get() {
+ // Another variant of Double Checked Locking.
+ //
+ // We use two volatile reads. We could reduce this to one by
+ // putting our fields into a holder class, but (at least on x86)
+ // the extra memory consumption and indirection are more
+ // expensive than the extra volatile reads.
+ long nanos = expirationNanos;
+ long now = System.nanoTime();
+ if (nanos == 0 || now - nanos >= 0) {
+ synchronized (this) {
+ if (nanos == expirationNanos) { // recheck for lost race
+
+ // Set value to null prior to retrieving new val, so old and new are not held in memory simultaneously
+ value = null;
+
+ T t = delegate.get();
+ value = t;
+
+ // Update now so that, if call was expensive, we keep value for the full duration
+ now = System.nanoTime();
+
+ nanos = now + durationNanos;
+ // In the very unlikely event that nanos is 0, set it to 1;
+ // no one will notice 1 ns of tardiness.
+ expirationNanos = (nanos == 0) ? 1 : nanos;
+ return t;
+ }
+ }
+ }
+ return value;
+ }
+
+ private static final long serialVersionUID = 0;
+ }
}
diff --git a/core/src/main/java/org/jclouds/util/Throwables2.java b/core/src/main/java/org/jclouds/util/Throwables2.java
index b7c1de8..559dfe7 100644
--- a/core/src/main/java/org/jclouds/util/Throwables2.java
+++ b/core/src/main/java/org/jclouds/util/Throwables2.java
@@ -80,12 +80,15 @@
return (Exception) throwable;
}
}
- for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class,
+ for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class, AssertionError.class,
UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class,
ResourceNotFoundException.class, InsufficientResourcesException.class, HttpResponseException.class }) {
Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType);
if (throwable != null) {
- throw (Exception) throwable;
+ if (throwable instanceof AssertionError)
+ throw (AssertionError) throwable;
+ else
+ throw (Exception) throwable;
}
}
Throwables.propagateIfPossible(exception.getCause(), Exception.class);
diff --git a/core/src/main/java/org/jclouds/xml/XMLParser.java b/core/src/main/java/org/jclouds/xml/XMLParser.java
index e79c521..cfb4e48 100644
--- a/core/src/main/java/org/jclouds/xml/XMLParser.java
+++ b/core/src/main/java/org/jclouds/xml/XMLParser.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.xml;
import java.io.IOException;
diff --git a/core/src/main/java/org/jclouds/xml/internal/JAXBParser.java b/core/src/main/java/org/jclouds/xml/internal/JAXBParser.java
index 928c725..65c5633 100644
--- a/core/src/main/java/org/jclouds/xml/internal/JAXBParser.java
+++ b/core/src/main/java/org/jclouds/xml/internal/JAXBParser.java
@@ -7,7 +7,7 @@
* "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
+ * 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
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.xml.internal;
import java.io.IOException;
diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties
index 854c6c5..9120345 100644
--- a/core/src/main/resources/rest.properties
+++ b/core/src/main/resources/rest.properties
@@ -4,7 +4,7 @@
azurequeue.contextbuilder=org.jclouds.azure.storage.AzureStorageContextBuilder
azurequeue.sync=org.jclouds.azurequeue.AzureQueueClient
azurequeue.async=org.jclouds.azurequeue.AzureQueueAsyncClient
-azurequeue.apiversion=2009-09-19
+azurequeue.api-version=2009-09-19
azurequeue.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
azurequeue.endpoint=https://{identity}.queue.core.windows.net
@@ -100,7 +100,7 @@
elasticstack.propertiesbuilder=org.jclouds.elasticstack.ElasticStackPropertiesBuilder
elasticstack.contextbuilder=org.jclouds.elasticstack.ElasticStackContextBuilder
-elasticstack.apiversion=1.0
+elasticstack.api-version=1.0
elastichosts-lon-p.propertiesbuilder=org.jclouds.elastichosts.ElasticHostsPeer1LondonPropertiesBuilder
elastichosts-lon-p.contextbuilder=org.jclouds.elasticstack.ElasticStackContextBuilder
@@ -153,7 +153,7 @@
atmos.contextbuilder=org.jclouds.atmos.AtmosContextBuilder
atmos.endpoint=https://accesspoint.atmosonline.com
-atmos.apiversion=1.3.0
+atmos.api-version=1.3.0
synaptic-storage.contextbuilder=org.jclouds.atmos.AtmosContextBuilder
synaptic-storage.propertiesbuilder=org.jclouds.synaptic.storage.SynapticStoragePropertiesBuilder
diff --git a/core/src/main/resources/rest.properties.orig b/core/src/main/resources/rest.properties.orig
deleted file mode 100644
index 11ee701..0000000
--- a/core/src/main/resources/rest.properties.orig
+++ /dev/null
@@ -1,106 +0,0 @@
-azurequeue.contextbuilder=org.jclouds.azure.storage.AzureStorageContextBuilder
-azurequeue.sync=org.jclouds.azure.storage.queue.AzureQueueClient
-azurequeue.async=org.jclouds.azure.storage.queue.AzureQueueAsyncClient
-azurequeue.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
-azurequeue.endpoint=https://{identity}.queue.core.windows.net
-
-azureblob.contextbuilder=org.jclouds.azure.storage.blob.AzureBlobContextBuilder
-azureblob.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
-azureblob.endpoint=https://{identity}.blob.core.windows.net
-
-pcs.contextbuilder=org.jclouds.mezeo.pcs2.PCSContextBuilder
-pcs.apiVersion=unknown
-
-sdn.contextbuilder=org.jclouds.nirvanix.sdn.SDNContextBuilder
-sdn.propertiesbuilder=org.jclouds.nirvanix.sdn.SDNPropertiesBuilder
-
-sqs.contextbuilder=org.jclouds.aws.sqs.SQSContextBuilder
-sqs.propertiesbuilder=org.jclouds.aws.sqs.SQSPropertiesBuilder
-
-elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder
-elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder
-
-cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
-cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder
-
-s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
-s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
-
-ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
-ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
-
-rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
-rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
-
-slicehost.contextbuilder=org.jclouds.slicehost.SlicehostContextBuilder
-slicehost.propertiesbuilder=org.jclouds.slicehost.SlicehostPropertiesBuilder
-
-trmk-vcloudexpress.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressContextBuilder
-trmk-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressPropertiesBuilder
-
-trmk-ecloud.contextbuilder=org.jclouds.vcloud.terremark.TerremarkECloudContextBuilder
-trmk-ecloud.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkECloudPropertiesBuilder
-
-chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
-chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
-
-transientchef.contextbuilder=org.jclouds.chef.test.TransientChefContextBuilder
-transientchef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
-
-opscodeplatform.contextbuilder=org.jclouds.opscodeplatform.OpscodePlatformContextBuilder
-opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPropertiesBuilder
-
-vcloud.contextbuilder=org.jclouds.vcloud.VCloudContextBuilder
-vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder
-
-vcloudexpress.contextbuilder=org.jclouds.vcloud.VCloudExpressContextBuilder
-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.VCloudExpressPropertiesBuilder
-
-eucalyptus.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
-eucalyptus.propertiesbuilder=org.jclouds.aws.ec2.EucalyptusPropertiesBuilder
-
-nova.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
-nova.propertiesbuilder=org.jclouds.aws.ec2.NovaPropertiesBuilder
-
-cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersContextBuilder
-cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder
-
-bluelock-vcdirector.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorContextBuilder
-bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorPropertiesBuilder
-
-gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder
-gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder
-
-ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder
-ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder
-
-stub.propertiesbuilder=org.jclouds.compute.stub.StubComputeServicePropertiesBuilder
-stub.contextbuilder=org.jclouds.compute.stub.StubComputeServiceContextBuilder
-# example of where to change your endpoint
-# bluelock.endpoint=https://express3.bluelock.com/api
-
-atmosonline.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
-atmosonline.endpoint=https://accesspoint.atmosonline.com
-atmosonline.apiversion=1.3.0
-
-synaptic.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
-synaptic.endpoint=https://storage.synaptic.att.com
-synaptic.apiversion=1.3.0
-
-# TODO peer1 and hostedsolutions use atmos
-
-cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuilder
-cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
-
-walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
-walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
-
-googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
-googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder
-
-transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
-transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
-
-filesystem.contextbuilder=org.jclouds.filesystem.FilesystemBlobStoreContextBuilder
-filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertiesBuilder
-
diff --git a/core/src/test/java/org/jclouds/JcloudsVersionTest.java b/core/src/test/java/org/jclouds/JcloudsVersionTest.java
new file mode 100644
index 0000000..99acf27
--- /dev/null
+++ b/core/src/test/java/org/jclouds/JcloudsVersionTest.java
@@ -0,0 +1,139 @@
+/**
+ * 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;
+
+import static org.jclouds.JcloudsVersion.VERSION_RESOURCE_FILE;
+import static org.testng.Assert.*;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Andrew Phillips
+ */
+@Test(singleThreaded = true)
+public class JcloudsVersionTest {
+
+ @Test
+ public void testFailsIfResourceFileMissing() {
+ ClassLoader original = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(
+ new ResourceHidingClassLoader(original, VERSION_RESOURCE_FILE));
+ try {
+ new JcloudsVersion();
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ } finally {
+ Thread.currentThread().setContextClassLoader(original);
+ }
+ }
+
+ @Test(expectedExceptions = { IllegalArgumentException.class })
+ public void testFailsIfInvalidVersion() {
+ new JcloudsVersion("${project.version}");
+ }
+
+ @Test
+ public void testExtractsVersionFromResourceFile() {
+ JcloudsVersion version = new JcloudsVersion();
+ assertEquals("0.0.0-SNAPSHOT", version.toString());
+ }
+
+ @Test
+ public void testExtractsMajorMinorPatchVersions() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3");
+ assertEquals(1, version.majorVersion);
+ assertEquals(2, version.minorVersion);
+ assertEquals(3, version.patchVersion);
+ }
+
+ @Test
+ public void testSupportsNonSnapshot() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3");
+ assertFalse(version.snapshot, "Expected non-snapshot");
+ }
+
+ @Test
+ public void testRecognisesSnapshot() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-SNAPSHOT");
+ assertTrue(version.snapshot, "Expected snapshot");
+ }
+
+ @Test
+ public void testSupportsNonReleaseCandidate() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3");
+ assertFalse(version.releaseCandidate, "Expected non-release candidate");
+ assertNull(version.releaseCandidateVersion);
+ }
+
+ @Test
+ public void testRecognisesReleaseCandidate() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-rc.4");
+ assertTrue(version.releaseCandidate, "Expected release candidate");
+ }
+
+ // TODO: remove once x.y.z-rc-n support is dropped after 1.3.0
+ @Test
+ public void testRecognisesNonSemverReleaseCandidate() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4");
+ assertTrue(version.releaseCandidate, "Expected release candidate");
+ }
+
+ @Test
+ public void testExtractsReleaseCandidateVersion() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-rc.4");
+ assertEquals(Integer.valueOf(4), version.releaseCandidateVersion);
+ }
+
+ // TODO: remove once x.y.z-rc-n support is dropped after 1.3.0
+ @Test
+ public void testExtractsNonSemverReleaseCandidateVersion() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4");
+ assertEquals(Integer.valueOf(4), version.releaseCandidateVersion);
+ }
+
+ @Test
+ public void testRecognisesReleaseCandidateSnapshot() {
+ JcloudsVersion version = new JcloudsVersion("1.2.3-rc-4-SNAPSHOT");
+ assertTrue(version.releaseCandidate, "Expected release candidate");
+ assertTrue(version.snapshot, "Expected snapshot");
+ }
+
+ private static class ResourceHidingClassLoader extends ClassLoader {
+ private final ClassLoader delegate;
+ private final List<String> resourcesToHide;
+
+ private ResourceHidingClassLoader(ClassLoader delegate, String... resourcesToHide) {
+ this.delegate = delegate;
+ this.resourcesToHide = ImmutableList.copyOf(resourcesToHide);
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String name) {
+ return (Iterables.contains(resourcesToHide, name)
+ ? null
+ : delegate.getResourceAsStream(name));
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/src/test/java/org/jclouds/domain/JsonBallTest.java b/core/src/test/java/org/jclouds/domain/JsonBallTest.java
index 7bfa390..ffc1e82 100644
--- a/core/src/test/java/org/jclouds/domain/JsonBallTest.java
+++ b/core/src/test/java/org/jclouds/domain/JsonBallTest.java
@@ -54,7 +54,7 @@
}
- public void testHash() {
+ public void testObject() {
String json = "{\"tomcat6\":{\"ssl_port\":8433}}";
Map<String, JsonBall> map = ImmutableMap.<String, JsonBall> of("tomcat6", new JsonBall("{\"ssl_port\":8433}"));
@@ -85,9 +85,20 @@
}
public void testNumber() {
- String json = "{\"number\":1}";
+ String json = "{\"number\":1.0}";
- Map<String, JsonBall> map = ImmutableMap.<String, JsonBall> of("number", new JsonBall("1"));
+ Map<String, JsonBall> map = ImmutableMap.<String, JsonBall> of("number", new JsonBall(1.0));
+
+ assertEquals(handler.apply(new HttpResponse(200, "ok", Payloads.newStringPayload(json))), map);
+ assertEquals(mapper.toJson(map), json);
+
+ }
+
+
+ public void testBoolean() {
+ String json = "{\"boolean\":false}";
+
+ Map<String, JsonBall> map = ImmutableMap.<String, JsonBall> of("boolean", new JsonBall(false));
assertEquals(handler.apply(new HttpResponse(200, "ok", Payloads.newStringPayload(json))), map);
assertEquals(mapper.toJson(map), json);
diff --git a/core/src/test/java/org/jclouds/http/BaseJettyTest.java b/core/src/test/java/org/jclouds/http/BaseJettyTest.java
index 90ba02b..3c09fd1 100644
--- a/core/src/test/java/org/jclouds/http/BaseJettyTest.java
+++ b/core/src/test/java/org/jclouds/http/BaseJettyTest.java
@@ -45,12 +45,13 @@
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.HttpHeaders;
+import org.eclipse.jetty.http.ssl.SslContextFactory;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.jclouds.Constants;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.io.InputSuppliers;
@@ -253,14 +254,18 @@
server2 = new Server();
server2.setHandler(server2Handler);
- SslSocketConnector ssl = new SslSocketConnector();
- ssl.setPort(testPort + 1);
- ssl.setMaxIdleTime(30000);
- ssl.setKeystore("src/test/resources/test.jks");
- ssl.setKeyPassword("jclouds");
- ssl.setTruststore("src/test/resources/test.jks");
- ssl.setTrustPassword("jclouds");
- server2.setConnectors(new Connector[] { ssl });
+
+ SslSelectChannelConnector ssl_connector = new SslSelectChannelConnector();
+ ssl_connector.setPort(testPort + 1);
+ ssl_connector.setMaxIdleTime(30000);
+ SslContextFactory ssl = ssl_connector.getSslContextFactory();
+ ssl.setKeyStorePath("src/test/resources/test.jks");
+ ssl.setKeyStorePassword("jclouds");
+ ssl.setTrustStore("src/test/resources/test.jks");
+ ssl.setTrustStorePassword("jclouds");
+
+ server2.setConnectors(new Connector[]{ ssl_connector });
+
server2.start();
}
@@ -282,7 +287,7 @@
properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test",
- "http://localhost:" + testPort, "1", "", "identity", null, IntegrationTestClient.class,
+ "http://localhost:" + testPort, "1", "", "", "identity", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class, ImmutableSet.<Module> copyOf(connectionModules));
return createContextBuilder(contextSpec, properties);
}
@@ -328,12 +333,10 @@
protected boolean failIfNoContentLength(HttpServletRequest request, HttpServletResponse response) throws IOException {
Multimap<String, String> realHeaders = LinkedHashMultimap.create();
- @SuppressWarnings("rawtypes")
- Enumeration headers = request.getHeaderNames();
+ Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String header = headers.nextElement().toString();
- @SuppressWarnings("rawtypes")
- Enumeration values = request.getHeaders(header);
+ Enumeration<String> values = request.getHeaders(header);
while (values.hasMoreElements()) {
realHeaders.put(header, values.nextElement().toString());
}
diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java
index 50d516d..694c298 100644
--- a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java
+++ b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java
@@ -48,6 +48,7 @@
import org.jclouds.rest.binders.BindMapToMatrixParams;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.binders.BindToStringPayload;
+import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.util.Strings2;
import com.google.common.base.Function;
@@ -73,6 +74,7 @@
@HEAD
@Path("/objects/{id}")
+ @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> exists(@PathParam("id") String path);
@GET
diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestClientExpectTest.java b/core/src/test/java/org/jclouds/http/IntegrationTestClientExpectTest.java
new file mode 100644
index 0000000..d584ef7
--- /dev/null
+++ b/core/src/test/java/org/jclouds/http/IntegrationTestClientExpectTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.http;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.jclouds.rest.BaseRestClientExpectTest.RegisterContext;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * Allows us to test a client via its side effects.
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "IntegrationTestClientExpectTest")
+// only needed as IntegrationTestClient is not registered in rest.properties
+@RegisterContext(sync = IntegrationTestClient.class, async = IntegrationTestAsyncClient.class)
+public class IntegrationTestClientExpectTest extends BaseRestClientExpectTest<IntegrationTestClient> {
+
+ public void testWhenResponseIs2xxExistsReturnsTrue() {
+
+ IntegrationTestClient client = requestSendsResponse(HttpRequest.builder().method("HEAD").endpoint(
+ URI.create("http://mock/objects/rabbit")).build(), HttpResponse.builder().statusCode(200).build());
+
+ assertEquals(client.exists("rabbit"), true);
+
+ }
+
+ public void testWhenResponseIs404ExistsReturnsFalse() {
+
+ IntegrationTestClient client = requestSendsResponse(HttpRequest.builder().method("HEAD").endpoint(
+ URI.create("http://mock/objects/rabbit")).build(), HttpResponse.builder().statusCode(404).build());
+
+ assertEquals(client.exists("rabbit"), false);
+
+ }
+}
diff --git a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
index b672608..db0dba6 100644
--- a/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
+++ b/core/src/test/java/org/jclouds/http/internal/TrackingJavaUrlHttpCommandExecutorService.java
@@ -1,3 +1,21 @@
+/**
+ * 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.http.internal;
import java.lang.reflect.Method;
diff --git a/core/src/test/java/org/jclouds/json/internal/NullHackJsonLiteralAdapterTest.java b/core/src/test/java/org/jclouds/json/internal/NullHackJsonLiteralAdapterTest.java
new file mode 100644
index 0000000..1a236ee
--- /dev/null
+++ b/core/src/test/java/org/jclouds/json/internal/NullHackJsonLiteralAdapterTest.java
@@ -0,0 +1,169 @@
+/**
+ * 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.json.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import org.jclouds.json.internal.NullHackJsonLiteralAdapter;
+import org.jclouds.util.Patterns;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Shows how we currently allow users to specify json literal types.
+ *
+ * @author Adrian Cole
+ * @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
+ */
+@Test(testName = "NullHackJsonLiteralAdapterTest")
+public class NullHackJsonLiteralAdapterTest {
+
+ /**
+ * User supplied type that holds json literally. Ex. number as {@code 8}, boolean as {@code true}
+ * , string as {@code "value"}, object as {@code , list {@code []}.
+ */
+ static class RawJson implements CharSequence {
+
+ private final String value;
+
+ public RawJson(double value) {
+ this.value = value + "";
+ }
+
+ public RawJson(boolean value) {
+ this.value = value + "";
+ }
+
+ public RawJson(String value) {
+ this.value = quoteStringIfNotNumberOrBoolean(checkNotNull(value, "value"));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ return Objects.equal(this.toString(), that.toString());
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ static String quoteStringIfNotNumberOrBoolean(String in) {
+ if (Patterns.JSON_STRING_PATTERN.matcher(in).find() && !Patterns.JSON_NUMBER_PATTERN.matcher(in).find()
+ && !Patterns.JSON_BOOLEAN_PATTERN.matcher(in).find()) {
+ return "\"" + in + "\"";
+ }
+ return in;
+ }
+
+ @Override
+ public char charAt(int index) {
+ return value.charAt(index);
+ }
+
+ @Override
+ public int length() {
+ return value.length();
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return value.subSequence(start, end);
+ }
+
+ }
+
+ /**
+ * writes or reads the literal directly
+ */
+ public static class RawJsonAdapter extends NullHackJsonLiteralAdapter<RawJson> {
+
+ @Override
+ protected RawJson createJsonLiteralFromRawJson(String json) {
+ return new RawJson(json);
+ }
+ }
+
+ // register the type adapter so that gson can serialize/deserialize to it
+ private Gson gsonAdapter = new GsonBuilder().registerTypeAdapter(RawJson.class, new RawJsonAdapter()).create();
+
+ Type type = new TypeToken<Map<String, RawJson>>() {
+ }.getType();
+
+ public void testObject() {
+ String json = "{\"tomcat6\":{\"ssl_port\":8433}}";
+
+ Map<String, RawJson> map = ImmutableMap.<String, RawJson> of("tomcat6", new RawJson("{\"ssl_port\":8433}"));
+
+ assertEquals(gsonAdapter.toJson(map), json);
+ assertEquals(gsonAdapter.fromJson(json, type), map);
+ }
+
+ public void testList() {
+ String json = "{\"list\":[8431,8433]}";
+
+ Map<String, RawJson> map = ImmutableMap.<String, RawJson> of("list", new RawJson("[8431,8433]"));
+
+ assertEquals(gsonAdapter.toJson(map), json);
+ assertEquals(gsonAdapter.fromJson(json, type), map);
+ }
+
+ public void testString() {
+ String json = "{\"name\":\"fooy\"}";
+
+ Map<String, RawJson> map = ImmutableMap.<String, RawJson> of("name", new RawJson("fooy"));
+
+ assertEquals(gsonAdapter.toJson(map), json);
+ assertEquals(gsonAdapter.fromJson(json, type), map);
+ }
+
+ public void testNumber() {
+ String json = "{\"number\":1.0}";
+
+ Map<String, RawJson> map = ImmutableMap.<String, RawJson> of("number", new RawJson(1.0));
+
+ assertEquals(gsonAdapter.toJson(map), json);
+ assertEquals(gsonAdapter.fromJson(json, type), map);
+ }
+
+ public void testBoolean() {
+ String json = "{\"boolean\":false}";
+
+ Map<String, RawJson> map = ImmutableMap.<String, RawJson> of("boolean", new RawJson(false));
+
+ assertEquals(gsonAdapter.toJson(map), json);
+ assertEquals(gsonAdapter.fromJson(json, type), map);
+ }
+}
diff --git a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java
index d31f217..7bdf751 100644
--- a/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java
+++ b/core/src/test/java/org/jclouds/lifecycle/config/LifeCycleModuleTest.java
@@ -27,6 +27,8 @@
import org.jclouds.Constants;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.lifecycle.Closer;
+
+import com.google.common.util.concurrent.ExecutionList;
import com.google.inject.name.Names;
import org.testng.annotations.Test;
@@ -75,6 +77,9 @@
return 1;
}
}, new ExecutorServiceModule());
+ // TODO: currently have to manually invoke the execution list, as otherwise it may occur
+ // before everything is wired up
+ i.getInstance(ExecutionList.class).execute();
return i;
}
diff --git a/core/src/test/java/org/jclouds/logging/BufferLogger.java b/core/src/test/java/org/jclouds/logging/BufferLogger.java
index 9618c01..083b92b 100644
--- a/core/src/test/java/org/jclouds/logging/BufferLogger.java
+++ b/core/src/test/java/org/jclouds/logging/BufferLogger.java
@@ -1,3 +1,21 @@
+/**
+ * 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.logging;
import java.util.ArrayList;
diff --git a/core/src/test/java/org/jclouds/logging/BufferLoggerTest.java b/core/src/test/java/org/jclouds/logging/BufferLoggerTest.java
index b054c8d..2954c8c 100644
--- a/core/src/test/java/org/jclouds/logging/BufferLoggerTest.java
+++ b/core/src/test/java/org/jclouds/logging/BufferLoggerTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.logging;
import java.util.logging.Level;
diff --git a/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java b/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java
new file mode 100644
index 0000000..61b54f2
--- /dev/null
+++ b/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java
@@ -0,0 +1,391 @@
+/**
+ * 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.rest;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.jclouds.rest.RestContextFactory.contextSpec;
+import static org.jclouds.rest.RestContextFactory.createContext;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.concurrent.MoreExecutors;
+import org.jclouds.concurrent.SingleThreaded;
+import org.jclouds.concurrent.config.ConfiguresExecutorService;
+import org.jclouds.http.HttpCommandExecutorService;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpUtils;
+import org.jclouds.http.IOExceptionRetryHandler;
+import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
+import org.jclouds.http.handlers.DelegatingErrorHandler;
+import org.jclouds.http.handlers.DelegatingRetryHandler;
+import org.jclouds.http.internal.BaseHttpCommandExecutorService;
+import org.jclouds.http.internal.HttpWire;
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.logging.config.NullLoggingModule;
+import org.jclouds.util.Strings2;
+import org.testng.annotations.Test;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.Binder;
+import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+
+/**
+ *
+ * Allows us to test a client via its side effects.
+ *
+ * <p/>
+ * Example usage:
+ *
+ * <pre>
+ *
+ * HttpRequest bucketFooExists = HttpRequest.builder().method("HEAD").endpoint(
+ * URI.create("https://foo.s3.amazonaws.com/?max-keys=0")).headers(
+ * ImmutableMultimap.<String, String> builder().put("Host", "foo.s3.amazonaws.com").put("Date", CONSTANT_DATE)
+ * .put("Authorization", "AWS identity:86P4BBb7xT+gBqq7jxM8Tc28ktY=").build()).build();
+ *
+ * S3Client clientWhenBucketExists = requestSendsResponse(bucketFooExists, HttpResponse.builder().statusCode(200).build());
+ * assert clientWhenBucketExists.bucketExists("foo");
+ *
+ * S3Client clientWhenBucketDoesntExist = requestSendsResponse(bucketFooExists, HttpResponse.builder().statusCode(404)
+ * .build());
+ * assert !clientWhenBucketDoesntExist.bucketExists("foo");
+ * </pre>
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit")
+@Beta
+public abstract class BaseRestClientExpectTest<S> {
+ /**
+ * only needed when the client is simple and not registered fn rest.properties
+ */
+ @Target(TYPE)
+ @Retention(RUNTIME)
+ public static @interface RegisterContext {
+ Class<?> sync();
+
+ Class<?> async();
+ }
+
+ protected String provider = "mock";
+
+ /**
+ * Override this to supply alternative bindings for use in the test. This is commonly used to
+ * override suppliers of dates so that the test results are predicatable.
+ *
+ * @return optional guice module which can override bindings
+ */
+ protected Module createModule() {
+ return new Module() {
+
+ @Override
+ public void configure(Binder binder) {
+
+ }
+
+ };
+ }
+
+ /**
+ * Convenience method used when creating a response that includes an http payload.
+ *
+ * <p/>
+ * ex.
+ *
+ * <pre>
+ * HttpResponse.builder().statusCode(200).payload(payloadFromResource("/ip_get_details.json")).build()
+ * </pre>
+ *
+ * @param resource
+ * resource file such as {@code /serverlist.json}
+ * @return payload for use in http responses.
+ */
+ public Payload payloadFromResource(String resource) {
+ return Payloads.newInputStreamPayload(getClass().getResourceAsStream(resource));
+ }
+
+ /**
+ * Mock executor service which uses the supplied function to return http responses.
+ */
+ @SingleThreaded
+ @Singleton
+ public static class ExpectHttpCommandExecutorService extends BaseHttpCommandExecutorService<HttpRequest> {
+
+ private final Function<HttpRequest, HttpResponse> fn;
+
+ @Inject
+ public ExpectHttpCommandExecutorService(Function<HttpRequest, HttpResponse> fn, HttpUtils utils,
+ @Named(Constants.PROPERTY_IO_WORKER_THREADS) ExecutorService ioExecutor,
+ IOExceptionRetryHandler ioRetryHandler, DelegatingRetryHandler retryHandler,
+ DelegatingErrorHandler errorHandler, HttpWire wire) {
+ super(utils, ioExecutor, retryHandler, ioRetryHandler, errorHandler, wire);
+ this.fn = checkNotNull(fn, "fn");
+ }
+
+ @Override
+ public void cleanup(HttpRequest nativeResponse) {
+ if (nativeResponse.getPayload() != null)
+ nativeResponse.getPayload().release();
+ }
+
+ @Override
+ public HttpRequest convert(HttpRequest request) throws IOException, InterruptedException {
+ return request;
+ }
+
+ @Override
+ public HttpResponse invoke(HttpRequest nativeRequest) throws IOException, InterruptedException {
+ return fn.apply(nativeRequest);
+ }
+ }
+
+ @ConfiguresHttpCommandExecutorService
+ @ConfiguresExecutorService
+ public static class ExpectModule extends AbstractModule {
+ private final Function<HttpRequest, HttpResponse> fn;
+
+ public ExpectModule(Function<HttpRequest, HttpResponse> fn) {
+ this.fn = checkNotNull(fn, "fn");
+ }
+
+ @Override
+ public void configure() {
+ bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).toInstance(
+ MoreExecutors.sameThreadExecutor());
+ bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).toInstance(
+ MoreExecutors.sameThreadExecutor());
+ bind(new TypeLiteral<Function<HttpRequest, HttpResponse>>() {
+ }).toInstance(fn);
+ bind(HttpCommandExecutorService.class).to(ExpectHttpCommandExecutorService.class);
+ }
+ }
+
+ /**
+ * creates a client for a mock server which only responds to a single http request
+ *
+ * @param request
+ * the http request the mock server responds to
+ * @param response
+ * the response the mock server returns for the request
+ * @return a client configured with this behavior
+ */
+ public S requestSendsResponse(HttpRequest request, HttpResponse response) {
+ return requestSendsResponse(request, response, createModule());
+ }
+
+ public S requestSendsResponse(HttpRequest request, HttpResponse response, Module module) {
+ return requestsSendResponses(ImmutableMap.of(request, response), module);
+ }
+
+ /**
+ * creates a client for a mock server which only responds to two types of requests
+ *
+ * @param requestA
+ * an http request the mock server responds to
+ * @param responseA
+ * the response for {@code requestA}
+ * @param requestB
+ * another http request the mock server responds to
+ * @param responseB
+ * the response for {@code requestB}
+ * @return a client configured with this behavior
+ */
+ public S requestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB) {
+ return requestsSendResponses(requestA, responseA, requestB, responseB, createModule());
+ }
+
+ public S requestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB, Module module) {
+ return requestsSendResponses(ImmutableMap.of(requestA, responseA, requestB, responseB), module);
+ }
+
+ /**
+ * creates a client for a mock server which only responds to three types of requests
+ *
+ * @param requestA
+ * an http request the mock server responds to
+ * @param responseA
+ * the response for {@code requestA}
+ * @param requestB
+ * another http request the mock server responds to
+ * @param responseB
+ * the response for {@code requestB}
+ * @param requestC
+ * another http request the mock server responds to
+ * @param responseC
+ * the response for {@code requestC}
+ * @return a client configured with this behavior
+ */
+ public S requestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB, HttpRequest requestC, HttpResponse responseC) {
+ return requestsSendResponses(requestA, responseA, requestB, responseB, requestC, responseC, createModule());
+ }
+
+ public S requestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB, HttpRequest requestC, HttpResponse responseC, Module module) {
+ return requestsSendResponses(ImmutableMap.of(requestA, responseA, requestB, responseB, requestC, responseC), module);
+ }
+
+ public S orderedRequestsSendResponses(HttpRequest requestA, HttpResponse responseA) {
+ return orderedRequestsSendResponses(ImmutableList.of(requestA), ImmutableList.of(responseA));
+ }
+
+ public S orderedRequestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB) {
+ return orderedRequestsSendResponses(ImmutableList.of(requestA, requestB), ImmutableList.of(responseA, responseB));
+ }
+
+ public S orderedRequestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB, HttpRequest requestC, HttpResponse responseC) {
+ return orderedRequestsSendResponses(ImmutableList.of(requestA, requestB, requestC), ImmutableList.of(responseA, responseB, responseC));
+ }
+
+ public S orderedRequestsSendResponses(HttpRequest requestA, HttpResponse responseA, HttpRequest requestB,
+ HttpResponse responseB, HttpRequest requestC, HttpResponse responseC, HttpRequest requestD, HttpResponse responseD) {
+ return orderedRequestsSendResponses(ImmutableList.of(requestA, requestB, requestC, requestD), ImmutableList.of(responseA, responseB, responseC, responseD));
+ }
+
+ public S orderedRequestsSendResponses(final List<HttpRequest> requests, final List<HttpResponse> responses) {
+ final AtomicInteger counter = new AtomicInteger(0);
+
+ return createClient(new Function<HttpRequest,HttpResponse>() {
+ @Override
+ public HttpResponse apply(HttpRequest input) {
+ int index = counter.getAndIncrement();
+ if (index >= requests.size()) {
+ throw new IndexOutOfBoundsException("request index "+index+", but only "+requests.size()+" request/response pairs");
+ }
+ assert input.equals(requests.get(index)) : "expected="+requests.get(index)+"; actual="+input;
+ return responses.get(index);
+ }
+ });
+ }
+
+ /**
+ * creates a client for a mock server which returns responses for requests based on the supplied
+ * Map parameter.
+ *
+ * @param requestToResponse
+ * valid requests and responses for the mock to respond to
+ * @return a client configured with this behavior
+ */
+ public S requestsSendResponses(Map<HttpRequest, HttpResponse> requestToResponse) {
+ return requestsSendResponses(requestToResponse, createModule());
+ }
+
+ public S requestsSendResponses(Map<HttpRequest, HttpResponse> requestToResponse, Module module) {
+ return createClient(Functions.forMap(requestToResponse), module);
+ }
+
+ public String renderRequest(HttpRequest request) {
+ StringBuilder builder = new StringBuilder().append(request.getRequestLine()).append('\n');
+ for (Entry<String, String> header : request.getHeaders().entries()) {
+ builder.append(header.getKey()).append(": ").append(header.getValue()).append('\n');
+ }
+ if (request.getPayload() != null) {
+ for (Entry<String, String> header : HttpUtils.getContentHeadersFromMetadata(
+ request.getPayload().getContentMetadata()).entries()) {
+ builder.append(header.getKey()).append(": ").append(header.getValue()).append('\n');
+ }
+ try {
+ builder.append('\n').append(Strings2.toStringAndClose(request.getPayload().getInput()));
+ } catch (IOException e) {
+ throw Throwables.propagate(e);
+ }
+
+ } else {
+ builder.append('\n');
+ }
+ return builder.toString();
+ }
+
+ public S createClient(Function<HttpRequest, HttpResponse> fn) {
+ return createClient(fn, createModule(), setupProperties());
+ }
+
+ public S createClient(Function<HttpRequest, HttpResponse> fn, Module module) {
+ return createClient(fn, module, setupProperties());
+
+ }
+
+ public S createClient(Function<HttpRequest, HttpResponse> fn, Properties props) {
+ return createClient(fn, createModule(), props);
+
+ }
+
+ public S createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
+ RestContextSpec<S, ?> contextSpec = makeContextSpec();
+
+ return createContext(contextSpec,
+ ImmutableSet.<Module> of(new ExpectModule(fn), new NullLoggingModule(), module), props).getApi();
+ }
+
+ @SuppressWarnings("unchecked")
+ private RestContextSpec<S, ?> makeContextSpec() {
+ if (getClass().isAnnotationPresent(RegisterContext.class))
+ return (RestContextSpec<S, ?>) contextSpec(provider, "http://mock", "1", "", "", "userfoo", null, getClass()
+ .getAnnotation(RegisterContext.class).sync(),
+ getClass().getAnnotation(RegisterContext.class).async(), ImmutableSet.<Module> of());
+ else
+ return new RestContextFactory(setupRestProperties()).createContextSpec(provider, "identity", "credential",
+ new Properties());
+ }
+
+ /**
+ * override this when the provider or api is not located in rest.properties and you are not using
+ * the {@link RegisterContext} annotation on your tests.
+ */
+ protected Properties setupRestProperties() {
+ return RestContextFactory.getPropertiesFromResource("/rest.properties");
+ }
+
+ /**
+ * override this to supply context-specific parameters during tests.
+ */
+ protected Properties setupProperties() {
+ return new Properties();
+ }
+}
\ No newline at end of file
diff --git a/core/src/test/java/org/jclouds/rest/BaseRestClientLiveTest.java b/core/src/test/java/org/jclouds/rest/BaseRestClientLiveTest.java
new file mode 100644
index 0000000..c4a787d
--- /dev/null
+++ b/core/src/test/java/org/jclouds/rest/BaseRestClientLiveTest.java
@@ -0,0 +1,82 @@
+/**
+ * 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.rest;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Strings.emptyToNull;
+
+import java.util.Properties;
+
+import org.jclouds.Constants;
+import org.testng.annotations.BeforeClass;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+public abstract class BaseRestClientLiveTest {
+ protected String prefix = System.getProperty("user.name");
+
+ protected String provider;
+ protected String identity;
+ protected String credential;
+ protected String endpoint;
+ protected String apiVersion;
+ protected String buildVersion;
+
+
+ protected Properties setupRestProperties() {
+ return RestContextFactory.getPropertiesFromResource("/rest.properties");
+ }
+
+ protected Properties setupProperties() {
+
+ if (emptyToNull(provider) == null)
+ throw new NullPointerException("provider must not be null or empty:" + provider);
+ if (emptyToNull(identity) == null)
+ throw new NullPointerException("identity must not be null or empty:" + provider);
+
+ Properties overrides = new Properties();
+ overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
+ overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
+
+ overrides.setProperty(provider + ".identity", identity);
+
+ if (credential != null)
+ overrides.setProperty(provider + ".credential", credential);
+ if (endpoint != null)
+ overrides.setProperty(provider + ".endpoint", endpoint);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
+ if (buildVersion != null)
+ overrides.setProperty(provider + ".build-version", buildVersion);
+
+ return overrides;
+ }
+
+ @BeforeClass
+ protected void setupCredentials() {
+ identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
+ credential = System.getProperty("test." + provider + ".credential");
+ endpoint = System.getProperty("test." + provider + ".endpoint");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
+ buildVersion = System.getProperty("test." + provider + ".build-version");
+ }
+
+}
diff --git a/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java b/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java
index b307a22..b052b05 100644
--- a/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java
+++ b/core/src/test/java/org/jclouds/rest/BaseRestClientTest.java
@@ -35,8 +35,8 @@
import org.jclouds.concurrent.config.ConfiguresExecutorService;
import org.jclouds.crypto.Crypto;
import org.jclouds.crypto.CryptoStreams;
+import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.HttpRequest;
-import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.io.MutableContentMetadata;
@@ -65,13 +65,13 @@
@ConfiguresHttpCommandExecutorService
@ConfiguresExecutorService
public static class MockModule extends AbstractModule {
- private final TransformingHttpCommandExecutorService mock;
+ private final HttpCommandExecutorService mock;
public MockModule() {
- this(createMock(TransformingHttpCommandExecutorService.class));
+ this(createMock(HttpCommandExecutorService.class));
}
- public MockModule(TransformingHttpCommandExecutorService mock) {
+ public MockModule(HttpCommandExecutorService mock) {
this.mock = mock;
}
@@ -81,7 +81,7 @@
MoreExecutors.sameThreadExecutor());
bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).toInstance(
MoreExecutors.sameThreadExecutor());
- bind(TransformingHttpCommandExecutorService.class).toInstance(mock);
+ bind(HttpCommandExecutorService.class).toInstance(mock);
}
}
diff --git a/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java b/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java
index 52bc193..108f14f 100644
--- a/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java
+++ b/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java
@@ -141,7 +141,7 @@
void setupFactory() {
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec("test",
- "http://localhost:9999", "1", "", "userFoo", null, IntegrationTestClient.class,
+ "http://localhost:9999", "1", "", "", "userFoo", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class);
injector = createContextBuilder(contextSpec).buildInjector();
diff --git a/core/src/test/java/org/jclouds/rest/RestClientTest.java b/core/src/test/java/org/jclouds/rest/RestClientTest.java
index c4bf0d7..627f07d 100644
--- a/core/src/test/java/org/jclouds/rest/RestClientTest.java
+++ b/core/src/test/java/org/jclouds/rest/RestClientTest.java
@@ -65,6 +65,7 @@
@BeforeClass
protected void setupFactory() throws IOException {
RestContextSpec<?, ?> contextSpec = createContextSpec();
+
injector = createContextBuilder(contextSpec,
ImmutableSet.of(new MockModule(), new NullLoggingModule(), createModule()), getProperties())
.buildInjector();
diff --git a/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java b/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java
index 0a1c31f..3dcfdd8 100644
--- a/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java
+++ b/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java
@@ -53,7 +53,7 @@
public void testBuilder() {
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", null, IntegrationTestClient.class,
+ "http://localhost", "1", "", "", "dummy", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class);
createContextBuilder(contextSpec);
@@ -61,12 +61,13 @@
public void testBuilderPropertiesWithIso3166() {
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "US-CA", "dummy", null, IntegrationTestClient.class,
+ "http://localhost", "1", "build-foo", "US-CA", "dummy", null, IntegrationTestClient.class,
IntegrationTestAsyncClient.class);
Properties props = RestContextFactory.toProperties(contextSpec);
assertEquals(props.getProperty("test.endpoint"), "http://localhost");
- assertEquals(props.getProperty("test.apiversion"), "1");
+ assertEquals(props.getProperty("test.api-version"), "1");
+ assertEquals(props.getProperty("test.build-version"), "build-foo");
assertEquals(props.getProperty("test.identity"), "dummy");
assertEquals(props.getProperty("test.iso3166-codes"), "US-CA");
assertEquals(props.getProperty("test.credential"), null);
@@ -81,12 +82,13 @@
public void testBuilderPropertiesWithCredential() {
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", "credential", IntegrationTestClient.class,
+ "http://localhost", "1", "build-foo", "", "dummy", "credential", IntegrationTestClient.class,
IntegrationTestAsyncClient.class);
Properties props = RestContextFactory.toProperties(contextSpec);
assertEquals(props.getProperty("test.endpoint"), "http://localhost");
- assertEquals(props.getProperty("test.apiversion"), "1");
+ assertEquals(props.getProperty("test.api-version"), "1");
+ assertEquals(props.getProperty("test.build-version"), "build-foo");
assertEquals(props.getProperty("test.identity"), "dummy");
assertEquals(props.getProperty("test.credential"), "credential");
assertEquals(props.getProperty("test.sync"), IntegrationTestClient.class.getName());
@@ -102,12 +104,13 @@
public void testBuilderPropertiesWithContextBuilder() {
@SuppressWarnings("rawtypes")
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
+ "http://localhost", "1", "build-foo", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
(Class) IntegrationTestContextBuilder.class, Collections.EMPTY_LIST);
Properties props = RestContextFactory.toProperties(contextSpec);
assertEquals(props.getProperty("test.endpoint"), "http://localhost");
- assertEquals(props.getProperty("test.apiversion"), "1");
+ assertEquals(props.getProperty("test.api-version"), "1");
+ assertEquals(props.getProperty("test.build-version"), "build-foo");
assertEquals(props.getProperty("test.identity"), "dummy");
assertEquals(props.getProperty("test.credential"), null);
assertEquals(props.getProperty("test.sync"), null);
@@ -123,12 +126,13 @@
public void testBuilderPropertiesWithModule() {
@SuppressWarnings("rawtypes")
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
+ "http://localhost", "1", "build-foo", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
(Class) IntegrationTestContextBuilder.class, Collections.<Module> singleton(new A()));
Properties props = RestContextFactory.toProperties(contextSpec);
assertEquals(props.getProperty("test.endpoint"), "http://localhost");
- assertEquals(props.getProperty("test.apiversion"), "1");
+ assertEquals(props.getProperty("test.api-version"), "1");
+ assertEquals(props.getProperty("test.build-version"), "build-foo");
assertEquals(props.getProperty("test.identity"), "dummy");
assertEquals(props.getProperty("test.credential"), null);
assertEquals(props.getProperty("test.sync"), null);
@@ -144,12 +148,13 @@
public void testBuilderPropertiesWithModules() {
@SuppressWarnings("rawtypes")
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
+ "http://localhost", "1", "build-foo", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class,
(Class) IntegrationTestContextBuilder.class, Arrays.<Module> asList(new A(), new B()));
Properties props = RestContextFactory.toProperties(contextSpec);
assertEquals(props.getProperty("test.endpoint"), "http://localhost");
- assertEquals(props.getProperty("test.apiversion"), "1");
+ assertEquals(props.getProperty("test.api-version"), "1");
+ assertEquals(props.getProperty("test.build-version"), "build-foo");
assertEquals(props.getProperty("test.identity"), "dummy");
assertEquals(props.getProperty("test.credential"), null);
assertEquals(props.getProperty("test.sync"), null);
@@ -165,7 +170,8 @@
public void testBuilderPropertiesJCloudsScope() {
Properties props = new Properties();
props.setProperty("test.endpoint", "http://localhost");
- props.setProperty("test.apiversion", "1");
+ props.setProperty("test.api-version", "1");
+ props.setProperty("test.build-version", "build-foo");
props.setProperty("test.iso3166-codes", "US");
props.setProperty("jclouds.identity", "foo");
props.setProperty("jclouds.credential", "bar");
@@ -186,6 +192,8 @@
assertEquals(spec.iso3166Codes, "US");
assertEquals(spec.identity, "foo");
assertEquals(spec.credential, "bar");
+ assertEquals(spec.apiVersion, "1");
+ assertEquals(spec.buildVersion, "build-foo");
assertEquals(Iterables.size(spec.modules), 2);
return spec;
}
@@ -200,7 +208,8 @@
Files.write("bar", file, Charsets.UTF_8);
Properties props = new Properties();
props.setProperty("test.endpoint", "http://localhost");
- props.setProperty("test.apiversion", "1");
+ props.setProperty("test.api-version", "1");
+ props.setProperty("test.build-version", "build-foo");
props.setProperty("test.iso3166-codes", "US");
props.setProperty("test.identity", "foo");
props.setProperty("test.credential.file", file.getAbsolutePath());
@@ -221,6 +230,8 @@
assertEquals(spec.iso3166Codes, "US");
assertEquals(spec.identity, "foo");
assertEquals(spec.credential, "bar");
+ assertEquals(spec.apiVersion, "1");
+ assertEquals(spec.buildVersion, "build-foo");
assertEquals(Iterables.size(spec.modules), 2);
return spec;
}
@@ -251,7 +262,7 @@
public void testBuilderPropertiesWithWrongConfig() {
@SuppressWarnings( { "unused", "rawtypes" })
RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> contextSpec = contextSpec(provider,
- "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null,
+ "http://localhost", "1", "build-foo", "", "dummy", null, (Class) null, (Class) null,
(Class) IntegrationTestContextBuilder.class, (Class) PropertiesBuilder.class, Collections.EMPTY_LIST);
}
diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java
index 5f2bbdc..51607f8 100644
--- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java
+++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java
@@ -20,12 +20,6 @@
import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.reportMatcher;
-import static org.easymock.classextension.EasyMock.createNiceMock;
-import static org.easymock.classextension.EasyMock.replay;
-import static org.easymock.classextension.EasyMock.verify;
import static org.jclouds.io.Payloads.calculateMD5;
import static org.jclouds.io.Payloads.newInputStreamPayload;
import static org.jclouds.io.Payloads.newStringPayload;
@@ -53,6 +47,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
@@ -75,26 +70,24 @@
import javax.ws.rs.core.UriBuilder;
import javax.xml.bind.annotation.XmlRootElement;
-import org.easymock.IArgumentMatcher;
import org.eclipse.jetty.http.HttpHeaders;
import org.jclouds.concurrent.Timeout;
import org.jclouds.crypto.Crypto;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpCommandExecutorService;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.IOExceptionRetryHandler;
import org.jclouds.http.RequiresHttp;
-import org.jclouds.http.TransformingHttpCommandExecutorService;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x;
import org.jclouds.http.functions.ParseXMLWithJAXB;
-import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnInputStream;
import org.jclouds.http.functions.ReturnStringIf2xx;
import org.jclouds.http.functions.ReturnTrueIf2xx;
@@ -180,8 +173,8 @@
@RequiresHttp
@ConfiguresRestClient
- protected static class CallerCalleeModule extends RestClientModule<Caller, AsyncCaller> {
- CallerCalleeModule() {
+ protected static class CallerModule extends RestClientModule<Caller, AsyncCaller> {
+ CallerModule() {
super(Caller.class, AsyncCaller.class, ImmutableMap.<Class<?>, Class<?>> of(Callee.class, AsyncCallee.class));
}
@@ -227,13 +220,17 @@
public AsyncCallee getCallee(@EndpointParam URI endpoint);
}
- @SuppressWarnings("unchecked")
- public void testDelegateAsyncIncludesVersion() throws SecurityException, NoSuchMethodException,
- InterruptedException, ExecutionException {
- Injector child = injectorForClient();
- TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class);
+ public void testAsyncDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException, ExecutionException {
+ Injector child = injectorForCaller(new HttpCommandExecutorService() {
- ReleasePayloadAndReturn function = child.getInstance(ReleasePayloadAndReturn.class);
+ @Override
+ public Future<HttpResponse> submit(HttpCommand command) {
+ assertEquals(command.getCurrentRequest().getRequestLine(),
+ "GET http://localhost:9999/client/1/foo HTTP/1.1");
+ return Futures.immediateFuture(HttpResponse.builder().build());
+ }
+
+ });
try {
child.getInstance(AsyncCallee.class);
@@ -242,42 +239,21 @@
}
- AsyncCaller caller = child.getInstance(AsyncCaller.class);
- expect(mock.submit(requestLineEquals("GET http://localhost:9999/client/1/foo HTTP/1.1"), eq(function)))
- .andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce();
- replay(mock);
-
- caller.getCallee().onePath("foo");
-
- verify(mock);
+ child.getInstance(AsyncCaller.class).getCallee().onePath("foo").get();
}
- public static HttpCommand requestLineEquals(final String requestLine) {
- reportMatcher(new IArgumentMatcher() {
+ public void testDelegateIsLazyLoadedAndRequestIncludesVersionAndPath() throws InterruptedException, ExecutionException {
+ Injector child = injectorForCaller(new HttpCommandExecutorService() {
@Override
- public void appendTo(StringBuffer buffer) {
- buffer.append("requestLineEquals(");
- buffer.append(requestLine);
- buffer.append(")");
- }
-
- @Override
- public boolean matches(Object arg) {
- return ((HttpCommand) arg).getCurrentRequest().getRequestLine().equals(requestLine);
+ public Future<HttpResponse> submit(HttpCommand command) {
+ assertEquals(command.getCurrentRequest().getRequestLine(),
+ "GET http://localhost:1111/client/1/foo HTTP/1.1");
+ return Futures.immediateFuture(HttpResponse.builder().build());
}
});
- return null;
- }
-
- public void testDelegateWithOverridingEndpoint() throws SecurityException, NoSuchMethodException,
- InterruptedException, ExecutionException {
- Injector child = injectorForClient();
- TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class);
-
- ReleasePayloadAndReturn function = child.getInstance(ReleasePayloadAndReturn.class);
try {
child.getInstance(Callee.class);
@@ -286,23 +262,45 @@
}
- Caller caller = child.getInstance(Caller.class);
- expect(mock.submit(requestLineEquals("GET http://localhost:1111/client/1/foo HTTP/1.1"), eq(function)))
- .andReturn(Futures.<Void> immediateFuture(null)).atLeastOnce();
- replay(mock);
+ child.getInstance(Caller.class).getCallee().onePath("foo");
- caller.getCallee().onePath("foo");
+ }
+
- verify(mock);
+ public void testAsyncDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException, ExecutionException {
+ Injector child = injectorForCaller(new HttpCommandExecutorService() {
+
+ @Override
+ public Future<HttpResponse> submit(HttpCommand command) {
+ assertEquals(command.getCurrentRequest().getRequestLine(),
+ "GET http://howdyboys/client/1/foo HTTP/1.1");
+ return Futures.immediateFuture(HttpResponse.builder().build());
+ }
+
+ });
+
+ try {
+ child.getInstance(AsyncCallee.class);
+ assert false : "Callee shouldn't be bound yet";
+ } catch (ConfigurationException e) {
+
+ }
+
+ child.getInstance(AsyncCaller.class).getCallee(URI.create("http://howdyboys")).onePath("foo").get();
}
- public void testDelegateWithOverridingEndpointOnMethod() throws SecurityException, NoSuchMethodException,
- InterruptedException, ExecutionException {
- Injector child = injectorForClient();
- TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class);
+ public void testDelegateIsLazyLoadedAndRequestIncludesEndpointVersionAndPath() throws InterruptedException, ExecutionException {
+ Injector child = injectorForCaller(new HttpCommandExecutorService() {
- ReleasePayloadAndReturn function = child.getInstance(ReleasePayloadAndReturn.class);
+ @Override
+ public Future<HttpResponse> submit(HttpCommand command) {
+ assertEquals(command.getCurrentRequest().getRequestLine(),
+ "GET http://howdyboys/client/1/foo HTTP/1.1");
+ return Futures.immediateFuture(HttpResponse.builder().build());
+ }
+
+ });
try {
child.getInstance(Callee.class);
@@ -311,22 +309,15 @@
}
- Caller caller = child.getInstance(Caller.class);
- expect(mock.submit(requestLineEquals("GET http://howdyboys/client/1/foo HTTP/1.1"), eq(function))).andReturn(
- Futures.<Void> immediateFuture(null)).atLeastOnce();
- replay(mock);
-
- caller.getCallee(URI.create("http://howdyboys")).onePath("foo");
-
- verify(mock);
+ child.getInstance(Caller.class).getCallee(URI.create("http://howdyboys")).onePath("foo");
}
+
+ private Injector injectorForCaller(HttpCommandExecutorService service) {
- private Injector injectorForClient() {
-
- RestContextSpec<Caller, AsyncCaller> contextSpec = contextSpec("test", "http://localhost:9999", "1", "",
- "userfoo", null, Caller.class, AsyncCaller.class,
- ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule(), new CallerCalleeModule()));
+ RestContextSpec<Caller, AsyncCaller> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "",
+ "userfoo", null, Caller.class, AsyncCaller.class, ImmutableSet.<Module> of(new MockModule(service),
+ new NullLoggingModule(), new CallerModule()));
return createContextBuilder(contextSpec).buildInjector();
@@ -2435,8 +2426,8 @@
@BeforeClass
void setupFactory() {
- RestContextSpec<String, Integer> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "userfoo",
- null, String.class, Integer.class,
+ RestContextSpec<Callee, AsyncCallee> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "", "userfoo",
+ null, Callee.class, AsyncCallee.class,
ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule(), new AbstractModule() {
@Override
diff --git a/core/src/test/java/org/jclouds/util/Suppliers2Test.java b/core/src/test/java/org/jclouds/util/Suppliers2Test.java
new file mode 100644
index 0000000..9319451
--- /dev/null
+++ b/core/src/test/java/org/jclouds/util/Suppliers2Test.java
@@ -0,0 +1,239 @@
+/**
+ * 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.util;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
+public class Suppliers2Test {
+
+ @Test
+ public void testMemoizeKeepsValueForFullDurationWhenDelegateCallIsSlow() {
+ final long SLEEP_TIME = 250;
+ final long EXPIRATION_TIME = 200;
+
+ Supplier<Integer> slowSupplier = new CountingSupplier() {
+ private static final long serialVersionUID = 1L;
+
+ @Override public Integer get() {
+ try {
+ Thread.sleep(SLEEP_TIME);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ return super.get();
+ }
+ };
+
+ Supplier<Integer> memoizedSupplier = Suppliers2.memoizeWithExpirationOnAbsoluteInterval(
+ slowSupplier, EXPIRATION_TIME, TimeUnit.MILLISECONDS);
+
+ assertEquals(memoizedSupplier.get(), (Integer)10);
+ assertEquals(memoizedSupplier.get(), (Integer)10);
+ }
+
+ // =================================
+ //
+ // TODO Everything below this point is taken from SuppliersTest, to test our version of the Suppliers2.memoizeWithExpiration
+ // It should be deleted when we can switch back to using the google Supplier.memoizeWithExpiration.
+
+ private static class CountingSupplier implements Supplier<Integer>, Serializable {
+ private static final long serialVersionUID = 0L;
+ transient int calls = 0;
+ @Override
+ public Integer get() {
+ calls++;
+ return calls * 10;
+ }
+ }
+
+ @Test
+ public void testMemoizeWithExpiration() throws InterruptedException {
+ CountingSupplier countingSupplier = new CountingSupplier();
+
+ Supplier<Integer> memoizedSupplier = Suppliers2.memoizeWithExpirationOnAbsoluteInterval(
+ countingSupplier, 75, TimeUnit.MILLISECONDS);
+
+ checkExpiration(countingSupplier, memoizedSupplier);
+ }
+
+ @Test
+ public void testMemoizeWithExpirationSerialized()
+ throws InterruptedException {
+ CountingSupplier countingSupplier = new CountingSupplier();
+
+ Supplier<Integer> memoizedSupplier = Suppliers2.memoizeWithExpirationOnAbsoluteInterval(
+ countingSupplier, 75, TimeUnit.MILLISECONDS);
+ // Calls to the original memoized supplier shouldn't affect its copy.
+ memoizedSupplier.get();
+
+ Supplier<Integer> copy = reserialize(memoizedSupplier);
+ memoizedSupplier.get();
+
+ CountingSupplier countingCopy = (CountingSupplier)
+ ((Suppliers2.ExpiringMemoizingSupplier<Integer>) copy).delegate;
+ checkExpiration(countingCopy, copy);
+ }
+
+ private void checkExpiration(
+ CountingSupplier countingSupplier, Supplier<Integer> memoizedSupplier)
+ throws InterruptedException {
+ // the underlying supplier hasn't executed yet
+ assertEquals(0, countingSupplier.calls);
+
+ assertEquals(10, (int) memoizedSupplier.get());
+ // now it has
+ assertEquals(1, countingSupplier.calls);
+
+ assertEquals(10, (int) memoizedSupplier.get());
+ // it still should only have executed once due to memoization
+ assertEquals(1, countingSupplier.calls);
+
+ Thread.sleep(150);
+
+ assertEquals(20, (int) memoizedSupplier.get());
+ // old value expired
+ assertEquals(2, countingSupplier.calls);
+
+ assertEquals(20, (int) memoizedSupplier.get());
+ // it still should only have executed twice due to memoization
+ assertEquals(2, countingSupplier.calls);
+ }
+
+ @Test
+ public void testExpiringMemoizedSupplierThreadSafe() throws Throwable {
+ Function<Supplier<Boolean>, Supplier<Boolean>> memoizer =
+ new Function<Supplier<Boolean>, Supplier<Boolean>>() {
+ @Override public Supplier<Boolean> apply(Supplier<Boolean> supplier) {
+ return Suppliers2.memoizeWithExpirationOnAbsoluteInterval(
+ supplier, Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ }
+ };
+ testSupplierThreadSafe(memoizer);
+ }
+
+ public void testSupplierThreadSafe(
+ Function<Supplier<Boolean>, Supplier<Boolean>> memoizer)
+ throws Throwable {
+ final AtomicInteger count = new AtomicInteger(0);
+ final AtomicReference<Throwable> thrown =
+ new AtomicReference<Throwable>(null);
+ final int numThreads = 3;
+ final Thread[] threads = new Thread[numThreads];
+ final long timeout = TimeUnit.SECONDS.toNanos(60);
+
+ final Supplier<Boolean> supplier = new Supplier<Boolean>() {
+ boolean isWaiting(Thread thread) {
+ switch (thread.getState()) {
+ case BLOCKED:
+ case WAITING:
+ case TIMED_WAITING:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ int waitingThreads() {
+ int waitingThreads = 0;
+ for (Thread thread : threads) {
+ if (isWaiting(thread)) {
+ waitingThreads++;
+ }
+ }
+ return waitingThreads;
+ }
+
+ @Override
+ public Boolean get() {
+ // Check that this method is called exactly once, by the first
+ // thread to synchronize.
+ long t0 = System.nanoTime();
+ while (waitingThreads() != numThreads - 1) {
+ if (System.nanoTime() - t0 > timeout) {
+ thrown.set(new TimeoutException(
+ "timed out waiting for other threads to block" +
+ " synchronizing on supplier"));
+ break;
+ }
+ Thread.yield();
+ }
+ count.getAndIncrement();
+ return Boolean.TRUE;
+ }
+ };
+
+ final Supplier<Boolean> memoizedSupplier = memoizer.apply(supplier);
+
+ for (int i = 0; i < numThreads; i++) {
+ threads[i] = new Thread() {
+ @Override public void run() {
+ assertSame(Boolean.TRUE, memoizedSupplier.get());
+ }
+ };
+ }
+ for (Thread t : threads) {
+ t.start();
+ }
+ for (Thread t : threads) {
+ t.join();
+ }
+
+ if (thrown.get() != null) {
+ throw thrown.get();
+ }
+ assertEquals(1, count.get());
+ }
+
+ // Taken from com.google.common.testing.SerializableTester
+ @SuppressWarnings("unchecked")
+ private static <T> T reserialize(T object) {
+ checkNotNull(object);
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ try {
+ ObjectOutputStream out = new ObjectOutputStream(bytes);
+ out.writeObject(object);
+ ObjectInputStream in = new ObjectInputStream(
+ new ByteArrayInputStream(bytes.toByteArray()));
+ return (T) in.readObject();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/core/src/test/java/org/jclouds/util/Throwables2Test.java b/core/src/test/java/org/jclouds/util/Throwables2Test.java
index f449fe7..ecc89b9 100644
--- a/core/src/test/java/org/jclouds/util/Throwables2Test.java
+++ b/core/src/test/java/org/jclouds/util/Throwables2Test.java
@@ -116,6 +116,12 @@
returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
}
+ @Test(expectedExceptions = AssertionError.class)
+ public void testPropagateStandardExceptionAssertionError() throws Exception {
+ AssertionError e = new AssertionError();
+ returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e));
+ }
+
@Test(expectedExceptions = AuthorizationException.class)
public void testPropagateStandardExceptionAuthorizationException() throws Exception {
Exception e = new AuthorizationException();
diff --git a/core/src/test/resources/META-INF/maven/org.jclouds/jclouds-core/pom.properties b/core/src/test/resources/META-INF/maven/org.jclouds/jclouds-core/pom.properties
new file mode 100644
index 0000000..6cc82e2
--- /dev/null
+++ b/core/src/test/resources/META-INF/maven/org.jclouds/jclouds-core/pom.properties
@@ -0,0 +1,4 @@
+# Dummy pom.properties file for testing
+version=0.0.0-SNAPSHOT
+groupId=org.jclouds
+artifactId=jclouds-core
diff --git a/demos/tweetstore/gae-tweetstore-spring/pom.xml b/demos/tweetstore/gae-tweetstore-spring/pom.xml
index 8ef5caa..7652afb 100644
--- a/demos/tweetstore/gae-tweetstore-spring/pom.xml
+++ b/demos/tweetstore/gae-tweetstore-spring/pom.xml
@@ -136,7 +136,7 @@
<plugin>
<groupId>net.kindleit</groupId>
<artifactId>maven-gae-plugin</artifactId>
- <version>0.9.1</version>
+ <version>0.9.2</version>
<configuration>
<serverId>google-appengine</serverId>
<sdkDir>${appengine.sdk.root}</sdkDir>
diff --git a/demos/tweetstore/gae-tweetstore/pom.xml b/demos/tweetstore/gae-tweetstore/pom.xml
index d1d5393..37a0d45 100644
--- a/demos/tweetstore/gae-tweetstore/pom.xml
+++ b/demos/tweetstore/gae-tweetstore/pom.xml
@@ -125,7 +125,7 @@
<plugin>
<groupId>net.kindleit</groupId>
<artifactId>maven-gae-plugin</artifactId>
- <version>0.8.4</version>
+ <version>0.9.2</version>
<configuration>
<serverId>google-appengine</serverId>
<sdkDir>${appengine.sdk.root}</sdkDir>
diff --git a/drivers/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java b/drivers/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java
index 6e107bf..a4081c4 100644
--- a/drivers/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java
+++ b/drivers/jsch/src/main/java/org/jclouds/ssh/jsch/JschSshClient.java
@@ -35,7 +35,6 @@
import java.net.ConnectException;
import java.util.Arrays;
-import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.inject.Named;
@@ -224,7 +223,6 @@
return null;
}
- @PostConstruct
public void connect() {
acquire(sessionConnection);
}
diff --git a/drivers/sshj/pom.xml b/drivers/sshj/pom.xml
index d47ecfc..1f72cb0 100644
--- a/drivers/sshj/pom.xml
+++ b/drivers/sshj/pom.xml
@@ -89,7 +89,7 @@
<dependency>
<groupId>net.schmizz</groupId>
<artifactId>sshj</artifactId>
- <version>0.6.1</version>
+ <version>0.7.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
diff --git a/drivers/sshj/src/main/java/org/jclouds/sshj/SshjSshClient.java b/drivers/sshj/src/main/java/org/jclouds/sshj/SshjSshClient.java
index 5bd3758..9427141 100644
--- a/drivers/sshj/src/main/java/org/jclouds/sshj/SshjSshClient.java
+++ b/drivers/sshj/src/main/java/org/jclouds/sshj/SshjSshClient.java
@@ -36,7 +36,6 @@
import java.net.SocketTimeoutException;
import java.util.concurrent.TimeUnit;
-import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.inject.Named;
@@ -248,7 +247,6 @@
return null;
}
- @PostConstruct
public void connect() {
try {
ssh = acquire(sshConnection);
diff --git a/loadbalancer/src/main/java/org/jclouds/loadbalancer/config/BaseLoadBalancerServiceContextModule.java b/loadbalancer/src/main/java/org/jclouds/loadbalancer/config/BaseLoadBalancerServiceContextModule.java
index 1f61d36..75a5a68 100644
--- a/loadbalancer/src/main/java/org/jclouds/loadbalancer/config/BaseLoadBalancerServiceContextModule.java
+++ b/loadbalancer/src/main/java/org/jclouds/loadbalancer/config/BaseLoadBalancerServiceContextModule.java
@@ -20,7 +20,6 @@
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
-import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@@ -32,10 +31,7 @@
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
-import com.google.common.base.Function;
import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -54,27 +50,6 @@
@Provides
@Singleton
- protected Supplier<Map<String, ? extends Location>> provideLocationMap(
- @Memoized Supplier<Set<? extends Location>> locations) {
- return Suppliers.compose(new Function<Set<? extends Location>, Map<String, ? extends Location>>() {
-
- @Override
- public Map<String, ? extends Location> apply(Set<? extends Location> from) {
- return Maps.uniqueIndex(from, new Function<Location, String>() {
-
- @Override
- public String apply(Location from) {
- return from.getId();
- }
-
- });
- }
-
- }, locations);
- }
-
- @Provides
- @Singleton
@Memoized
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Location>> locationSupplier) {
diff --git a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
index c797dfa..9fa21cf 100644
--- a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
+++ b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java
@@ -55,7 +55,7 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true)
public abstract class BaseLoadBalancerServiceLiveTest extends BaseVersionedServiceLiveTest {
protected SshClient.Factory sshFactory;
@@ -74,6 +74,7 @@
protected String computeCredential;
protected String computeEndpoint;
protected String computeApiversion;
+ protected String computeBuildversion;
protected ComputeServiceContext computeContext;
@Override
@@ -85,7 +86,8 @@
+ ".compute.identity");
computeCredential = System.getProperty("test." + provider + ".compute.credential");
computeEndpoint = System.getProperty("test." + provider + ".compute.endpoint");
- computeApiversion = System.getProperty("test." + provider + ".compute.apiversion");
+ computeApiversion = System.getProperty("test." + provider + ".compute.api-version");
+ computeBuildversion = System.getProperty("test." + provider + ".compute.build-version");
}
protected Properties setupComputeProperties() {
@@ -98,7 +100,9 @@
if (computeEndpoint != null)
overrides.setProperty(computeProvider + ".endpoint", computeEndpoint);
if (computeApiversion != null)
- overrides.setProperty(computeProvider + ".apiversion", computeApiversion);
+ overrides.setProperty(computeProvider + ".api-version", computeApiversion);
+ if (computeBuildversion != null)
+ overrides.setProperty(computeProvider + ".build-version", computeBuildversion);
return overrides;
}
diff --git a/project/pom.xml b/project/pom.xml
index dbbc587..bf7f149 100644
--- a/project/pom.xml
+++ b/project/pom.xml
@@ -206,8 +206,13 @@
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-server</artifactId>
+ <version>8.0.4.v20111024</version>
+ </dependency>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
- <version>7.4.0.RC0</version>
+ <version>8.0.4.v20111024</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
@@ -276,7 +281,7 @@
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
- <version>1.3.3</version>
+ <version>1.3.8</version>
<configuration>
<sourceDirectories>
<sourceDirectory>src/main/clojure</sourceDirectory>
diff --git a/providers/aws-cloudwatch/pom.xml b/providers/aws-cloudwatch/pom.xml
index 013a1b7..d77927a 100644
--- a/providers/aws-cloudwatch/pom.xml
+++ b/providers/aws-cloudwatch/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.aws-cloudwatch.endpoint>https://monitoring.us-east-1.amazonaws.com</test.aws-cloudwatch.endpoint>
- <test.aws-cloudwatch.apiversion>2009-05-15</test.aws-cloudwatch.apiversion>
+ <test.aws-cloudwatch.api-version>2009-05-15</test.aws-cloudwatch.api-version>
+ <test.aws-cloudwatch.build-version></test.aws-cloudwatch.build-version>
<test.aws-cloudwatch.identity>${test.aws.identity}</test.aws-cloudwatch.identity>
<test.aws-cloudwatch.credential>${test.aws.credential}</test.aws-cloudwatch.credential>
</properties>
@@ -87,12 +88,13 @@
<configuration>
<systemPropertyVariables>
<test.aws-cloudwatch.endpoint>${test.aws-cloudwatch.endpoint}</test.aws-cloudwatch.endpoint>
- <test.aws-cloudwatch.apiversion>${test.aws-cloudwatch.apiversion}</test.aws-cloudwatch.apiversion>
+ <test.aws-cloudwatch.api-version>${test.aws-cloudwatch.api-version}</test.aws-cloudwatch.api-version>
+ <test.aws-cloudwatch.build-version>${test.aws-cloudwatch.build-version}</test.aws-cloudwatch.build-version>
<test.aws-cloudwatch.identity>${test.aws-cloudwatch.identity}</test.aws-cloudwatch.identity>
<test.aws-cloudwatch.credential>${test.aws-cloudwatch.credential}</test.aws-cloudwatch.credential>
<test.aws-cloudwatch.compute.provider>${test.aws-cloudwatch.compute.provider}</test.aws-cloudwatch.compute.provider>
<test.aws-cloudwatch.compute.endpoint>${test.aws-cloudwatch.compute.endpoint}</test.aws-cloudwatch.compute.endpoint>
- <test.aws-cloudwatch.compute.apiversion>${test.aws-cloudwatch.compute.apiversion}</test.aws-cloudwatch.compute.apiversion>
+ <test.aws-cloudwatch.compute.api-version>${test.aws-cloudwatch.compute.api-version}</test.aws-cloudwatch.compute.api-version>
<test.aws-cloudwatch.compute.identity>${test.aws-cloudwatch.compute.identity}</test.aws-cloudwatch.compute.identity>
<test.aws-cloudwatch.compute.credential>${test.aws-cloudwatch.compute.credential}</test.aws-cloudwatch.compute.credential>
</systemPropertyVariables>
diff --git a/providers/aws-ec2/pom.xml b/providers/aws-ec2/pom.xml
index e3477d5..9328e8d 100644
--- a/providers/aws-ec2/pom.xml
+++ b/providers/aws-ec2/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.aws-ec2.endpoint>https://ec2.us-east-1.amazonaws.com</test.aws-ec2.endpoint>
- <test.aws-ec2.apiversion>2011-05-15</test.aws-ec2.apiversion>
+ <test.aws-ec2.api-version>2011-05-15</test.aws-ec2.api-version>
+ <test.aws-ec2.build-version></test.aws-ec2.build-version>
<test.aws-ec2.identity>${test.aws.identity}</test.aws-ec2.identity>
<test.aws-ec2.credential>${test.aws.credential}</test.aws-ec2.credential>
<test.aws-ec2.image-id />
@@ -113,7 +114,8 @@
<configuration>
<systemPropertyVariables>
<test.aws-ec2.endpoint>${test.aws-ec2.endpoint}</test.aws-ec2.endpoint>
- <test.aws-ec2.apiversion>${test.aws-ec2.apiversion}</test.aws-ec2.apiversion>
+ <test.aws-ec2.api-version>${test.aws-ec2.api-version}</test.aws-ec2.api-version>
+ <test.aws-ec2.build-version>${test.aws-ec2.build-version}</test.aws-ec2.build-version>
<test.aws-ec2.identity>${test.aws-ec2.identity}</test.aws-ec2.identity>
<test.aws-ec2.credential>${test.aws-ec2.credential}</test.aws-ec2.credential>
<test.aws-ec2.image-id>${test.aws-ec2.image-id}</test.aws-ec2.image-id>
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
index 2f03987..b1dd1d1 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2ImageSupplier.java
@@ -34,6 +34,7 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import com.google.common.collect.ForwardingSet;
import org.jclouds.Constants;
import org.jclouds.aws.ec2.compute.config.ClusterCompute;
import org.jclouds.compute.domain.Image;
@@ -127,7 +128,11 @@
logger.debug("<< images(%d)", imageMap.size());
// TODO Used to be mutable; was this assumed anywhere?
- return ImmutableSet.copyOf(imageMap.values());
+ return new ForwardingSet<Image>() {
+ protected Set<Image> delegate() {
+ return ImmutableSet.copyOf(cache.get().asMap().values());
+ }
+ };
}
private Future<Iterable<Image>> images(Iterable<String> regions, String query, String tag) {
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java
index c62cff6..8d41a26 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AMIClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.AWSDescribeImagesOptions.Builder.filters;
import static org.jclouds.aws.ec2.options.AWSDescribeImagesOptions.Builder.imageIds;
import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice;
@@ -30,22 +29,32 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Image;
+import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RootDeviceType;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.domain.Snapshot;
import org.jclouds.ec2.domain.Image.ImageType;
import org.jclouds.ec2.services.AMIClient;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
@@ -59,50 +68,29 @@
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true)
-public class AMIClientLiveTest {
-
+public class AMIClientLiveTest extends BaseVersionedServiceLiveTest {
+ public AMIClientLiveTest() {
+ provider = "aws-ec2";
+ // TODO: parameterize this.
+ imageId = "ami-cdf819a4";
+ }
+
private AMIClient client;
- private String imageId = "ami-cdf819a4";
private static final String DEFAULT_MANIFEST = "adrianimages/image.manifest.xml";
private static final String DEFAULT_SNAPSHOT = "TODO";
private RestContext<EC2Client, EC2AsyncClient> context;
private Set<String> imagesToDeregister = Sets.newHashSet();
+ private Set<String> snapshotsToDelete = Sets.newHashSet();
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
+ private ComputeServiceContext jcloudsContext;
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
- context = new ComputeServiceContextFactory().createContext(provider,
- ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
+ jcloudsContext = new ComputeServiceContextFactory().createContext(provider,
+ ImmutableSet.<Module>of(new Log4JLoggingModule()), overrides);
+ context = jcloudsContext.getProviderSpecificContext();
client = context.getApi().getAMIServices();
}
@@ -175,6 +163,50 @@
assertEquals(imageRegisteredFromManifestWithOptions.getDescription(), "adrian");
}
+ @Test
+ public void testNewlyRegisteredImageCanBeListed() throws Exception {
+ ComputeService computeService = jcloudsContext.getComputeService();
+ Snapshot snapshot = createSnapshot(computeService);
+
+ // List of images before...
+ int sizeBefore = computeService.listImages().size();
+
+ // Register a new image...
+ final String imageRegisteredId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest1", snapshot.getId());
+ imagesToDeregister.add(imageRegisteredId);
+ final Image imageRegistered = Iterables.getOnlyElement(client.describeImagesInRegion(null, imageIds(imageRegisteredId)));
+
+ // This is the suggested method to ensure the new image ID is inserted into the cache
+ // (suggested by adriancole_ on #jclouds)
+ computeService.templateBuilder().imageId(imageRegistered.getRegion() + "/" + imageRegisteredId).build();
+
+ // List of images after - should be one larger than before
+ Set<? extends org.jclouds.compute.domain.Image> after = computeService.listImages();
+ assertEquals(after.size(), sizeBefore + 1);
+
+ // Detailed check: filter for the AMI ID
+ Iterable<? extends org.jclouds.compute.domain.Image> filtered = Iterables.filter(after,
+ ImagePredicates.idEquals(imageRegistered.getRegion() + "/" + imageRegisteredId));
+ assertEquals(Iterables.size(filtered), 1);
+ }
+
+ // Fires up an instance, finds its root volume ID, takes a snapshot, then terminates the instance.
+ private Snapshot createSnapshot(ComputeService computeService) throws RunNodesException {
+ Template options = computeService.templateBuilder().smallest().build();
+ Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup("jcloudstest", 1, options);
+ try {
+ String instanceId = Iterables.getOnlyElement(nodes).getProviderId();
+ Reservation<? extends RunningInstance> reservation = Iterables.getOnlyElement(context.getApi().getInstanceServices().describeInstancesInRegion(null, instanceId));
+ RunningInstance instance = Iterables.getOnlyElement(reservation);
+ BlockDevice device = instance.getEbsBlockDevices().get("/dev/sda1");
+ Snapshot snapshot = context.getApi().getElasticBlockStoreServices().createSnapshotInRegion(null, device.getVolumeId());
+ snapshotsToDelete.add(snapshot.getId());
+ return snapshot;
+ } finally {
+ computeService.destroyNodesMatching(Predicates.in(nodes));
+ }
+ }
+
@Test(enabled = false)
// awaiting EBS functionality to be added to jclouds
public void testRegisterImageBackedByEBS() {
@@ -245,8 +277,10 @@
}
@AfterTest
- public void deregisterImages() {
+ public void cleanUp() {
for (String imageId : imagesToDeregister)
client.deregisterImageInRegion(null, imageId);
+ for (String snapshotId : snapshotsToDelete)
+ context.getApi().getElasticBlockStoreServices().deleteSnapshotInRegion(null, snapshotId);
}
}
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java
index a46e6b9..ebeeb4c 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.AWSDescribeImagesOptions.Builder.imageIds;
import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice;
import static org.jclouds.ec2.options.RegisterImageOptions.Builder.withDescription;
@@ -29,9 +28,9 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.domain.Image;
import org.jclouds.ec2.domain.RootDeviceType;
@@ -40,7 +39,6 @@
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -55,45 +53,21 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class AWSAMIClientLiveTest {
-
+@Test(groups = "live", singleThreaded = true, testName = "AWSAMIClientLiveTest")
+public class AWSAMIClientLiveTest extends BaseVersionedServiceLiveTest {
+ public AWSAMIClientLiveTest() {
+ provider = "aws-ec2";
+ // TODO: parameterize this.
+ imageId = "ami-7ea24a17";
+ }
+
private AWSAMIClient client;
- private String imageId = "ami-7ea24a17";
private static final String DEFAULT_MANIFEST = "adrianimages/image.manifest.xml";
private static final String DEFAULT_SNAPSHOT = "TODO";
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
private Set<String> imagesToDeregister = Sets.newHashSet();
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java
index 6f59c9e..5554a5b 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java
@@ -18,15 +18,14 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull;
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
@@ -44,39 +43,17 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class AWSInstanceClientLiveTest {
+@Test(groups = "live", singleThreaded = true)
+public class AWSInstanceClientLiveTest extends BaseVersionedServiceLiveTest {
+ public AWSInstanceClientLiveTest() {
+ provider = "aws-ec2";
+ }
+
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
private AWSInstanceClient client;
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
+
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSKeyPairClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSKeyPairClientLiveTest.java
index fb6bb41..efe34ee 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSKeyPairClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSKeyPairClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.get;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.collect.Sets.newTreeSet;
@@ -36,12 +35,12 @@
import java.util.Set;
import java.util.SortedSet;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.ComputeTestUtils;
@@ -66,39 +65,16 @@
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true)
-public class AWSKeyPairClientLiveTest {
+public class AWSKeyPairClientLiveTest extends BaseVersionedServiceLiveTest {
+ public AWSKeyPairClientLiveTest() {
+ provider = "aws-ec2";
+ }
private AWSKeyPairClient client;
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
private ComputeServiceContext computeContext;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint", null);
- apiversion = System.getProperty("test." + provider + ".apiversion", null);
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java
index b729c09..4cd81c9 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java
@@ -18,16 +18,15 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.Properties;
-import org.jclouds.Constants;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.MonitoringState;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
@@ -42,37 +41,16 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class MonitoringClientLiveTest {
+@Test(groups = "live", singleThreaded = true)
+public class MonitoringClientLiveTest extends BaseVersionedServiceLiveTest {
+ public MonitoringClientLiveTest() {
+ provider = "aws-ec2";
+ }
private MonitoringClient client;
private static final String DEFAULT_INSTANCE = "i-TODO";
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java
index e4ff0a2..96f4002 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newTreeSet;
@@ -33,13 +32,13 @@
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.PlacementGroup;
import org.jclouds.aws.ec2.domain.PlacementGroup.State;
import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable;
import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
@@ -54,7 +53,6 @@
import org.jclouds.scriptbuilder.statements.login.AdminAccess;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -68,40 +66,16 @@
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "PlacementGroupClientLiveTest")
-public class PlacementGroupClientLiveTest {
+public class PlacementGroupClientLiveTest extends BaseVersionedServiceLiveTest {
+ public PlacementGroupClientLiveTest() {
+ provider = "aws-ec2";
+ }
private AWSEC2Client client;
private ComputeServiceContext context;
private RetryablePredicate<PlacementGroup> availableTester;
private RetryablePredicate<PlacementGroup> deletedTester;
private PlacementGroup group;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() throws FileNotFoundException, IOException {
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/SpotInstanceClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/SpotInstanceClientLiveTest.java
index fc06e17..7a4d638 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/SpotInstanceClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/SpotInstanceClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.in;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions.Builder.from;
@@ -34,7 +33,6 @@
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
@@ -42,6 +40,7 @@
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.predicates.SpotInstanceRequestActive;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.ec2.domain.InstanceType;
@@ -49,7 +48,6 @@
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -63,43 +61,19 @@
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true)
-public class SpotInstanceClientLiveTest {
+public class SpotInstanceClientLiveTest extends BaseVersionedServiceLiveTest {
+ public SpotInstanceClientLiveTest() {
+ provider = "aws-ec2";
+ }
private static final int SPOT_DELAY_SECONDS = 600;
private AWSEC2Client client;
private ComputeServiceContext context;
private RetryablePredicate<SpotInstanceRequest> activeTester;
private Set<SpotInstanceRequest> requests;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
private AWSRunningInstance instance;
private long start;
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() throws FileNotFoundException, IOException {
setupCredentials();
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/TagClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/TagClientLiveTest.java
index 88239d4..901b52d 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/TagClientLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/TagClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.aws.ec2.services;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -26,13 +25,13 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
import org.jclouds.aws.ec2.domain.Tag;
import org.jclouds.aws.ec2.util.TagFilters;
import org.jclouds.aws.ec2.util.TagFilters.ResourceType;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@@ -55,38 +54,17 @@
* @author grkvlt@apache.org
*/
@Test(groups = "live", singleThreaded = true)
-public class TagClientLiveTest {
+public class TagClientLiveTest extends BaseVersionedServiceLiveTest {
+ public TagClientLiveTest() {
+ provider = "aws-ec2";
+ }
private TagClient client;
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
- protected String provider = "aws-ec2";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected String testGroup;
private ComputeServiceContext computeContext;
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint", null);
- apiversion = System.getProperty("test." + provider + ".apiversion", null);
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClientAndSecurityGroup() {
diff --git a/providers/aws-s3/pom.xml b/providers/aws-s3/pom.xml
index a332487..2ffd814 100644
--- a/providers/aws-s3/pom.xml
+++ b/providers/aws-s3/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.aws.s3.blobstore.integration.AWSS3TestInitializer</test.initializer>
<test.aws-s3.endpoint>https://s3.amazonaws.com</test.aws-s3.endpoint>
- <test.aws-s3.apiversion>2006-03-01</test.aws-s3.apiversion>
+ <test.aws-s3.api-version>2006-03-01</test.aws-s3.api-version>
+ <test.aws-s3.build-version></test.aws-s3.build-version>
<test.aws-s3.identity>${test.aws.identity}</test.aws-s3.identity>
<test.aws-s3.credential>${test.aws.credential}</test.aws-s3.credential>
<test.blobstore.container-count>25</test.blobstore.container-count>
@@ -123,7 +124,8 @@
<configuration>
<systemPropertyVariables>
<test.aws-s3.endpoint>${test.aws-s3.endpoint}</test.aws-s3.endpoint>
- <test.aws-s3.apiversion>${test.aws-s3.apiversion}</test.aws-s3.apiversion>
+ <test.aws-s3.api-version>${test.aws-s3.api-version}</test.aws-s3.api-version>
+ <test.aws-s3.build-version>${test.aws-s3.build-version}</test.aws-s3.build-version>
<test.aws-s3.identity>${test.aws-s3.identity}</test.aws-s3.identity>
<test.aws-s3.credential>${test.aws-s3.credential}</test.aws-s3.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/binders/BindObjectMetadataToRequestTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/binders/BindObjectMetadataToRequestTest.java
index 118b42a..1c0c811 100644
--- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/binders/BindObjectMetadataToRequestTest.java
+++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/binders/BindObjectMetadataToRequestTest.java
@@ -28,10 +28,10 @@
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
-import org.jclouds.s3.BaseS3AsyncClientTest;
import org.jclouds.s3.S3AsyncClient;
import org.jclouds.s3.domain.ObjectMetadata;
import org.jclouds.s3.domain.ObjectMetadataBuilder;
+import org.jclouds.s3.internal.BaseS3AsyncClientTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3TestInitializer.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3TestInitializer.java
index 37d13a8..5ba408b 100644
--- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3TestInitializer.java
+++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3TestInitializer.java
@@ -42,11 +42,11 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule(), new EnterpriseConfigurationModule()), setupProperties(endpoint, apiversion,
- identity, credential));
+ new Log4JLoggingModule(), new EnterpriseConfigurationModule()), setupProperties(endpoint, apiVersion,
+ buildVersion, identity, credential));
}
}
diff --git a/providers/azureblob/pom.xml b/providers/azureblob/pom.xml
index f7d398f..e573264 100644
--- a/providers/azureblob/pom.xml
+++ b/providers/azureblob/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.azureblob.blobstore.integration.AzureBlobTestInitializer</test.initializer>
<test.azureblob.endpoint>https://{identity}.blob.core.windows.net</test.azureblob.endpoint>
- <test.azureblob.apiversion>2009-09-19</test.azureblob.apiversion>
+ <test.azureblob.api-version>2009-09-19</test.azureblob.api-version>
+ <test.azureblob.build-version></test.azureblob.build-version>
<test.azureblob.identity>${test.azure.identity}</test.azureblob.identity>
<test.azureblob.credential>${test.azure.credential}</test.azureblob.credential>
</properties>
@@ -94,7 +95,8 @@
<configuration>
<systemPropertyVariables>
<test.azureblob.endpoint>${test.azureblob.endpoint}</test.azureblob.endpoint>
- <test.azureblob.apiversion>${test.azureblob.apiversion}</test.azureblob.apiversion>
+ <test.azureblob.api-version>${test.azureblob.api-version}</test.azureblob.api-version>
+ <test.azureblob.build-version>${test.azureblob.build-version}</test.azureblob.build-version>
<test.azureblob.identity>${test.azureblob.identity}</test.azureblob.identity>
<test.azureblob.credential>${test.azureblob.credential}</test.azureblob.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
index 118739b..22ecdfc 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
@@ -18,10 +18,9 @@
*/
package org.jclouds.azureblob;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
import static org.jclouds.azureblob.options.CreateContainerOptions.Builder.withMetadata;
import static org.jclouds.azureblob.options.CreateContainerOptions.Builder.withPublicAccess;
-import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@@ -32,16 +31,15 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
import org.jclouds.azure.storage.AzureStorageResponseException;
+import org.jclouds.azure.storage.domain.BoundedSet;
+import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azureblob.domain.AzureBlob;
import org.jclouds.azureblob.domain.BlobProperties;
import org.jclouds.azureblob.domain.ContainerProperties;
import org.jclouds.azureblob.domain.ListBlobsResponse;
import org.jclouds.azureblob.domain.PublicAccess;
import org.jclouds.azureblob.options.ListBlobsOptions;
-import org.jclouds.azure.storage.domain.BoundedSet;
-import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.BlobStoreContextFactory;
import org.jclouds.blobstore.ContainerNotFoundException;
@@ -50,6 +48,7 @@
import org.jclouds.http.options.GetOptions;
import org.jclouds.io.Payloads;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
+import org.jclouds.rest.BaseRestClientLiveTest;
import org.jclouds.util.Strings2;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@@ -65,40 +64,14 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class AzureBlobClientLiveTest {
-
+@Test(groups = "live", singleThreaded = true)
+public class AzureBlobClientLiveTest extends BaseRestClientLiveTest {
+ public AzureBlobClientLiveTest() {
+ provider = "azureblob";
+ }
protected AzureBlobClient client;
- private String containerPrefix = System.getProperty("user.name") + "-azureblob";
-
private BlobStoreContext context;
- protected String provider = "azureblob";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (credential != null)
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
@@ -125,7 +98,7 @@
public void testCreateContainer() throws Exception {
boolean created = false;
while (!created) {
- privateContainer = containerPrefix + new SecureRandom().nextInt();
+ privateContainer = prefix + new SecureRandom().nextInt();
try {
created = client.createContainer(privateContainer, withMetadata(ImmutableMultimap.of("foo", "bar")));
} catch (UndeclaredThrowableException e) {
@@ -149,7 +122,7 @@
public void testCreatePublicContainer() throws Exception {
boolean created = false;
while (!created) {
- publicContainer = containerPrefix + new SecureRandom().nextInt();
+ publicContainer = prefix + new SecureRandom().nextInt();
try {
created = client.createContainer(publicContainer, withPublicAccess(PublicAccess.BLOB));
} catch (UndeclaredThrowableException e) {
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobTestInitializer.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobTestInitializer.java
index 51b817c..5dfcd0a 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobTestInitializer.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobTestInitializer.java
@@ -39,10 +39,10 @@
}
@Override
- protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion,
- String app, String identity, String credential) throws IOException {
+ protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
+ String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
- new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential));
+ new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
}
}
diff --git a/providers/bluelock-vcloud-zone01/pom.xml b/providers/bluelock-vcloud-zone01/pom.xml
index 559ee9e..8ae52a6 100644
--- a/providers/bluelock-vcloud-zone01/pom.xml
+++ b/providers/bluelock-vcloud-zone01/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.bluelock-vcloud-zone01.endpoint>https://zone01.bluelock.com/api</test.bluelock-vcloud-zone01.endpoint>
- <test.bluelock-vcloud-zone01.apiversion>1.0</test.bluelock-vcloud-zone01.apiversion>
+ <test.bluelock-vcloud-zone01.api-version>1.0</test.bluelock-vcloud-zone01.api-version>
+ <test.bluelock-vcloud-zone01.build-version></test.bluelock-vcloud-zone01.build-version>
<test.bluelock-vcloud-zone01.identity>FIXME_IDENTITY</test.bluelock-vcloud-zone01.identity>
<test.bluelock-vcloud-zone01.credential>FIXME_CREDENTIAL</test.bluelock-vcloud-zone01.credential>
<test.bluelock-vcloud-zone01.image-id />
@@ -102,7 +103,8 @@
<configuration>
<systemPropertyVariables>
<test.bluelock-vcloud-zone01.endpoint>${test.bluelock-vcloud-zone01.endpoint}</test.bluelock-vcloud-zone01.endpoint>
- <test.bluelock-vcloud-zone01.apiversion>${test.bluelock-vcloud-zone01.apiversion}</test.bluelock-vcloud-zone01.apiversion>
+ <test.bluelock-vcloud-zone01.api-version>${test.bluelock-vcloud-zone01.api-version}</test.bluelock-vcloud-zone01.api-version>
+ <test.bluelock-vcloud-zone01.build-version>${test.bluelock-vcloud-zone01.build-version}</test.bluelock-vcloud-zone01.build-version>
<test.bluelock-vcloud-zone01.identity>${test.bluelock-vcloud-zone01.identity}</test.bluelock-vcloud-zone01.identity>
<test.bluelock-vcloud-zone01.credential>${test.bluelock-vcloud-zone01.credential}</test.bluelock-vcloud-zone01.credential>
<test.bluelock-vcloud-zone01.image-id>${test.bluelock-vcloud-zone01.image-id}</test.bluelock-vcloud-zone01.image-id>
diff --git a/providers/cloudfiles-uk/pom.xml b/providers/cloudfiles-uk/pom.xml
index 866ed52..2afc244 100644
--- a/providers/cloudfiles-uk/pom.xml
+++ b/providers/cloudfiles-uk/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesUKTestInitializer</test.initializer>
<test.cloudfiles-uk.endpoint>https://lon.auth.api.rackspacecloud.com</test.cloudfiles-uk.endpoint>
- <test.cloudfiles-uk.apiversion>1.0</test.cloudfiles-uk.apiversion>
+ <test.cloudfiles-uk.api-version>1.0</test.cloudfiles-uk.api-version>
+ <test.cloudfiles-uk.build-version></test.cloudfiles-uk.build-version>
<test.cloudfiles-uk.identity>${test.rackspace-uk.identity}</test.cloudfiles-uk.identity>
<test.cloudfiles-uk.credential>${test.rackspace-uk.credential}</test.cloudfiles-uk.credential>
</properties>
@@ -109,7 +110,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.cloudfiles-uk.endpoint>${test.cloudfiles-uk.endpoint}</test.cloudfiles-uk.endpoint>
- <test.cloudfiles-uk.apiversion>${test.cloudfiles-uk.apiversion}</test.cloudfiles-uk.apiversion>
+ <test.cloudfiles-uk.api-version>${test.cloudfiles-uk.api-version}</test.cloudfiles-uk.api-version>
+ <test.cloudfiles-uk.build-version>${test.cloudfiles-uk.build-version}</test.cloudfiles-uk.build-version>
<test.cloudfiles-uk.identity>${test.cloudfiles-uk.identity}</test.cloudfiles-uk.identity>
<test.cloudfiles-uk.credential>${test.cloudfiles-uk.credential}</test.cloudfiles-uk.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/cloudfiles-us/pom.xml b/providers/cloudfiles-us/pom.xml
index 5a1ee41..c7df756 100644
--- a/providers/cloudfiles-us/pom.xml
+++ b/providers/cloudfiles-us/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesUSTestInitializer</test.initializer>
<test.cloudfiles-us.endpoint>https://auth.api.rackspacecloud.com</test.cloudfiles-us.endpoint>
- <test.cloudfiles-us.apiversion>1.0</test.cloudfiles-us.apiversion>
+ <test.cloudfiles-us.api-version>1.0</test.cloudfiles-us.api-version>
+ <test.cloudfiles-us.build-version></test.cloudfiles-us.build-version>
<test.cloudfiles-us.identity>${test.rackspace-us.identity}</test.cloudfiles-us.identity>
<test.cloudfiles-us.credential>${test.rackspace-us.credential}</test.cloudfiles-us.credential>
</properties>
@@ -109,7 +110,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.cloudfiles-us.endpoint>${test.cloudfiles-us.endpoint}</test.cloudfiles-us.endpoint>
- <test.cloudfiles-us.apiversion>${test.cloudfiles-us.apiversion}</test.cloudfiles-us.apiversion>
+ <test.cloudfiles-us.api-version>${test.cloudfiles-us.api-version}</test.cloudfiles-us.api-version>
+ <test.cloudfiles-us.build-version>${test.cloudfiles-us.build-version}</test.cloudfiles-us.build-version>
<test.cloudfiles-us.identity>${test.cloudfiles-us.identity}</test.cloudfiles-us.identity>
<test.cloudfiles-us.credential>${test.cloudfiles-us.credential}</test.cloudfiles-us.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/cloudloadbalancers-uk/pom.xml b/providers/cloudloadbalancers-uk/pom.xml
index cff5c9e..6ca7dbd 100644
--- a/providers/cloudloadbalancers-uk/pom.xml
+++ b/providers/cloudloadbalancers-uk/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudloadbalancers-uk.endpoint>https://lon.auth.api.rackspacecloud.com</test.cloudloadbalancers-uk.endpoint>
- <test.cloudloadbalancers-uk.apiversion>1.0</test.cloudloadbalancers-uk.apiversion>
+ <test.cloudloadbalancers-uk.api-version>1.0</test.cloudloadbalancers-uk.api-version>
+ <test.cloudloadbalancers-uk.build-version></test.cloudloadbalancers-uk.build-version>
<test.cloudloadbalancers-uk.identity>${test.rackspace-uk.identity}</test.cloudloadbalancers-uk.identity>
<test.cloudloadbalancers-uk.credential>${test.rackspace-uk.credential}</test.cloudloadbalancers-uk.credential>
</properties>
@@ -109,7 +110,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudloadbalancers-uk.endpoint>${test.cloudloadbalancers-uk.endpoint}</test.cloudloadbalancers-uk.endpoint>
- <test.cloudloadbalancers-uk.apiversion>${test.cloudloadbalancers-uk.apiversion}</test.cloudloadbalancers-uk.apiversion>
+ <test.cloudloadbalancers-uk.api-version>${test.cloudloadbalancers-uk.api-version}</test.cloudloadbalancers-uk.api-version>
+ <test.cloudloadbalancers-uk.build-version>${test.cloudloadbalancers-uk.build-version}</test.cloudloadbalancers-uk.build-version>
<test.cloudloadbalancers-uk.identity>${test.cloudloadbalancers-uk.identity}</test.cloudloadbalancers-uk.identity>
<test.cloudloadbalancers-uk.credential>${test.cloudloadbalancers-uk.credential}</test.cloudloadbalancers-uk.credential>
</systemPropertyVariables>
diff --git a/providers/cloudloadbalancers-us/pom.xml b/providers/cloudloadbalancers-us/pom.xml
index efc0c4a..d702ea7 100644
--- a/providers/cloudloadbalancers-us/pom.xml
+++ b/providers/cloudloadbalancers-us/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudloadbalancers-us.endpoint>https://auth.api.rackspacecloud.com</test.cloudloadbalancers-us.endpoint>
- <test.cloudloadbalancers-us.apiversion>1.0</test.cloudloadbalancers-us.apiversion>
+ <test.cloudloadbalancers-us.api-version>1.0</test.cloudloadbalancers-us.api-version>
+ <test.cloudloadbalancers-us.build-version></test.cloudloadbalancers-us.build-version>
<test.cloudloadbalancers-us.identity>${test.rackspace-us.identity}</test.cloudloadbalancers-us.identity>
<test.cloudloadbalancers-us.credential>${test.rackspace-us.credential}</test.cloudloadbalancers-us.credential>
</properties>
@@ -109,7 +110,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudloadbalancers-us.endpoint>${test.cloudloadbalancers-us.endpoint}</test.cloudloadbalancers-us.endpoint>
- <test.cloudloadbalancers-us.apiversion>${test.cloudloadbalancers-us.apiversion}</test.cloudloadbalancers-us.apiversion>
+ <test.cloudloadbalancers-us.api-version>${test.cloudloadbalancers-us.api-version}</test.cloudloadbalancers-us.api-version>
+ <test.cloudloadbalancers-us.build-version>${test.cloudloadbalancers-us.build-version}</test.cloudloadbalancers-us.build-version>
<test.cloudloadbalancers-us.identity>${test.cloudloadbalancers-us.identity}</test.cloudloadbalancers-us.identity>
<test.cloudloadbalancers-us.credential>${test.cloudloadbalancers-us.credential}</test.cloudloadbalancers-us.credential>
</systemPropertyVariables>
diff --git a/providers/cloudonestorage/pom.xml b/providers/cloudonestorage/pom.xml
index 4c43998..14a5fbd 100644
--- a/providers/cloudonestorage/pom.xml
+++ b/providers/cloudonestorage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.cloudonestorage.blobstore.integration.CloudOneStorageTestInitializer</test.initializer>
<test.cloudonestorage.endpoint>https://cloudonestorage.peer1.com</test.cloudonestorage.endpoint>
- <test.cloudonestorage.apiversion>1.3.0</test.cloudonestorage.apiversion>
+ <test.cloudonestorage.api-version>1.3.0</test.cloudonestorage.api-version>
+ <test.cloudonestorage.build-version></test.cloudonestorage.build-version>
<test.cloudonestorage.identity>FIXME_IDENTITY</test.cloudonestorage.identity>
<test.cloudonestorage.credential>FIXME_CREDENTIAL</test.cloudonestorage.credential>
</properties>
@@ -102,7 +103,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.cloudonestorage.endpoint>${test.cloudonestorage.endpoint}</test.cloudonestorage.endpoint>
- <test.cloudonestorage.apiversion>${test.cloudonestorage.apiversion}</test.cloudonestorage.apiversion>
+ <test.cloudonestorage.api-version>${test.cloudonestorage.api-version}</test.cloudonestorage.api-version>
+ <test.cloudonestorage.build-version>${test.cloudonestorage.build-version}</test.cloudonestorage.build-version>
<test.cloudonestorage.identity>${test.cloudonestorage.identity}</test.cloudonestorage.identity>
<test.cloudonestorage.credential>${test.cloudonestorage.credential}</test.cloudonestorage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/cloudservers-uk/pom.xml b/providers/cloudservers-uk/pom.xml
index 685c6fc..f9b32e7 100644
--- a/providers/cloudservers-uk/pom.xml
+++ b/providers/cloudservers-uk/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudservers-uk.endpoint>https://lon.auth.api.rackspacecloud.com</test.cloudservers-uk.endpoint>
- <test.cloudservers-uk.apiversion>1.0</test.cloudservers-uk.apiversion>
+ <test.cloudservers-uk.api-version>1.0</test.cloudservers-uk.api-version>
+ <test.cloudservers-uk.build-version></test.cloudservers-uk.build-version>
<test.cloudservers-uk.identity>${test.rackspace-uk.identity}</test.cloudservers-uk.identity>
<test.cloudservers-uk.credential>${test.rackspace-uk.credential}</test.cloudservers-uk.credential>
<test.cloudservers-uk.image-id />
@@ -107,7 +108,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudservers-uk.endpoint>${test.cloudservers-uk.endpoint}</test.cloudservers-uk.endpoint>
- <test.cloudservers-uk.apiversion>${test.cloudservers-uk.apiversion}</test.cloudservers-uk.apiversion>
+ <test.cloudservers-uk.api-version>${test.cloudservers-uk.api-version}</test.cloudservers-uk.api-version>
+ <test.cloudservers-uk.build-version>${test.cloudservers-uk.build-version}</test.cloudservers-uk.build-version>
<test.cloudservers-uk.identity>${test.cloudservers-uk.identity}</test.cloudservers-uk.identity>
<test.cloudservers-uk.credential>${test.cloudservers-uk.credential}</test.cloudservers-uk.credential>
<test.cloudservers-uk.image-id>${test.cloudservers-uk.image-id}</test.cloudservers-uk.image-id>
diff --git a/providers/cloudservers-us/pom.xml b/providers/cloudservers-us/pom.xml
index 1fc747a..657d41c 100644
--- a/providers/cloudservers-us/pom.xml
+++ b/providers/cloudservers-us/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudservers-us.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers-us.endpoint>
- <test.cloudservers-us.apiversion>1.0</test.cloudservers-us.apiversion>
+ <test.cloudservers-us.api-version>1.0</test.cloudservers-us.api-version>
+ <test.cloudservers-us.build-version></test.cloudservers-us.build-version>
<test.cloudservers-us.identity>${test.rackspace-us.identity}</test.cloudservers-us.identity>
<test.cloudservers-us.credential>${test.rackspace-us.credential}</test.cloudservers-us.credential>
<test.cloudservers-us.image-id />
@@ -108,7 +109,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.cloudservers-us.endpoint>${test.cloudservers-us.endpoint}</test.cloudservers-us.endpoint>
- <test.cloudservers-us.apiversion>${test.cloudservers-us.apiversion}</test.cloudservers-us.apiversion>
+ <test.cloudservers-us.api-version>${test.cloudservers-us.api-version}</test.cloudservers-us.api-version>
+ <test.cloudservers-us.build-version>${test.cloudservers-us.build-version}</test.cloudservers-us.build-version>
<test.cloudservers-us.identity>${test.cloudservers-us.identity}</test.cloudservers-us.identity>
<test.cloudservers-us.credential>${test.cloudservers-us.credential}</test.cloudservers-us.credential>
<test.cloudservers-us.image-id>${test.cloudservers-us.image-id}</test.cloudservers-us.image-id>
diff --git a/providers/cloudsigma-lvs/pom.xml b/providers/cloudsigma-lvs/pom.xml
index 073d1b6..c4a66aa 100644
--- a/providers/cloudsigma-lvs/pom.xml
+++ b/providers/cloudsigma-lvs/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudsigma-lvs.endpoint>https://api.lvs.cloudsigma.com</test.cloudsigma-lvs.endpoint>
- <test.cloudsigma-lvs.apiversion>1.0</test.cloudsigma-lvs.apiversion>
+ <test.cloudsigma-lvs.api-version>1.0</test.cloudsigma-lvs.api-version>
+ <test.cloudsigma-lvs.build-version></test.cloudsigma-lvs.build-version>
<test.cloudsigma-lvs.identity>FIXME</test.cloudsigma-lvs.identity>
<test.cloudsigma-lvs.credential>FIXME</test.cloudsigma-lvs.credential>
<test.cloudsigma-lvs.image-id />
@@ -102,7 +103,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudsigma-lvs.endpoint>${test.cloudsigma-lvs.endpoint}</test.cloudsigma-lvs.endpoint>
- <test.cloudsigma-lvs.apiversion>${test.cloudsigma-lvs.apiversion}</test.cloudsigma-lvs.apiversion>
+ <test.cloudsigma-lvs.api-version>${test.cloudsigma-lvs.api-version}</test.cloudsigma-lvs.api-version>
+ <test.cloudsigma-lvs.build-version>${test.cloudsigma-lvs.build-version}</test.cloudsigma-lvs.build-version>
<test.cloudsigma-lvs.identity>${test.cloudsigma-lvs.identity}</test.cloudsigma-lvs.identity>
<test.cloudsigma-lvs.credential>${test.cloudsigma-lvs.credential}</test.cloudsigma-lvs.credential>
<test.cloudsigma-lvs.image-id>${test.cloudsigma-lvs.image-id}</test.cloudsigma-lvs.image-id>
diff --git a/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/CloudSigmaLasVegasLondonClientLiveTest.java b/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/CloudSigmaLasVegasLondonClientLiveTest.java
index 024d895..a3cbcd3 100644
--- a/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/CloudSigmaLasVegasLondonClientLiveTest.java
+++ b/providers/cloudsigma-lvs/src/test/java/org/jclouds/cloudsigma/CloudSigmaLasVegasLondonClientLiveTest.java
@@ -29,6 +29,5 @@
public class CloudSigmaLasVegasLondonClientLiveTest extends CloudSigmaClientLiveTest {
public CloudSigmaLasVegasLondonClientLiveTest() {
provider = "cloudsigma-lvs";
- bootDrive = "af8bfee4-d249-4d91-b157-b01ee1ce1943";
}
}
diff --git a/providers/cloudsigma-zrh/pom.xml b/providers/cloudsigma-zrh/pom.xml
index 5741c2a..0ef7ab4 100644
--- a/providers/cloudsigma-zrh/pom.xml
+++ b/providers/cloudsigma-zrh/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.cloudsigma-zrh.endpoint>https://api.zrh.cloudsigma.com</test.cloudsigma-zrh.endpoint>
- <test.cloudsigma-zrh.apiversion>1.0</test.cloudsigma-zrh.apiversion>
+ <test.cloudsigma-zrh.api-version>1.0</test.cloudsigma-zrh.api-version>
+ <test.cloudsigma-zrh.build-version></test.cloudsigma-zrh.build-version>
<test.cloudsigma-zrh.identity>FIXME</test.cloudsigma-zrh.identity>
<test.cloudsigma-zrh.credential>FIXME</test.cloudsigma-zrh.credential>
<test.cloudsigma-zrh.image-id />
@@ -102,7 +103,8 @@
<configuration>
<systemPropertyVariables>
<test.cloudsigma-zrh.endpoint>${test.cloudsigma-zrh.endpoint}</test.cloudsigma-zrh.endpoint>
- <test.cloudsigma-zrh.apiversion>${test.cloudsigma-zrh.apiversion}</test.cloudsigma-zrh.apiversion>
+ <test.cloudsigma-zrh.api-version>${test.cloudsigma-zrh.api-version}</test.cloudsigma-zrh.api-version>
+ <test.cloudsigma-zrh.build-version>${test.cloudsigma-zrh.build-version}</test.cloudsigma-zrh.build-version>
<test.cloudsigma-zrh.identity>${test.cloudsigma-zrh.identity}</test.cloudsigma-zrh.identity>
<test.cloudsigma-zrh.credential>${test.cloudsigma-zrh.credential}</test.cloudsigma-zrh.credential>
<test.cloudsigma-zrh.image-id>${test.cloudsigma-zrh.image-id}</test.cloudsigma-zrh.image-id>
diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaZurichClientLiveTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaZurichClientLiveTest.java
index 5ccfc93..d326ee7 100644
--- a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaZurichClientLiveTest.java
+++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaZurichClientLiveTest.java
@@ -29,6 +29,5 @@
public class CloudSigmaZurichClientLiveTest extends CloudSigmaClientLiveTest {
public CloudSigmaZurichClientLiveTest() {
provider = "cloudsigma-zrh";
- bootDrive = "7fad4fe1-daf3-4cb8-a847-082aae4d8506";
}
}
diff --git a/providers/elastichosts-lax-p/pom.xml b/providers/elastichosts-lax-p/pom.xml
index ee8ac09..1c7b6cd 100644
--- a/providers/elastichosts-lax-p/pom.xml
+++ b/providers/elastichosts-lax-p/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.elastichosts-lax-p.endpoint>https://api.lax-p.elastichosts.com</test.elastichosts-lax-p.endpoint>
- <test.elastichosts-lax-p.apiversion>2.0</test.elastichosts-lax-p.apiversion>
+ <test.elastichosts-lax-p.api-version>2.0</test.elastichosts-lax-p.api-version>
+ <test.elastichosts-lax-p.build-version></test.elastichosts-lax-p.build-version>
<test.elastichosts-lax-p.identity>FIXME_IDENTITY</test.elastichosts-lax-p.identity>
<test.elastichosts-lax-p.credential>FIXME_CREDENTIAL</test.elastichosts-lax-p.credential>
<test.elastichosts-lax-p.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.elastichosts-lax-p.endpoint>${test.elastichosts-lax-p.endpoint}</test.elastichosts-lax-p.endpoint>
- <test.elastichosts-lax-p.apiversion>${test.elastichosts-lax-p.apiversion}</test.elastichosts-lax-p.apiversion>
+ <test.elastichosts-lax-p.api-version>${test.elastichosts-lax-p.api-version}</test.elastichosts-lax-p.api-version>
+ <test.elastichosts-lax-p.build-version>${test.elastichosts-lax-p.build-version}</test.elastichosts-lax-p.build-version>
<test.elastichosts-lax-p.identity>${test.elastichosts-lax-p.identity}</test.elastichosts-lax-p.identity>
<test.elastichosts-lax-p.credential>${test.elastichosts-lax-p.credential}</test.elastichosts-lax-p.credential>
<test.elastichosts-lax-p.image-id>${test.elastichosts-lax-p.image-id}</test.elastichosts-lax-p.image-id>
diff --git a/providers/elastichosts-lax-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LosAngelesClientLiveTest.java b/providers/elastichosts-lax-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LosAngelesClientLiveTest.java
index 53e8046..3f86bdb 100644
--- a/providers/elastichosts-lax-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LosAngelesClientLiveTest.java
+++ b/providers/elastichosts-lax-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LosAngelesClientLiveTest.java
@@ -25,10 +25,10 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "ElasticHostsPeer1LosAngelesClientLiveTest")
public class ElasticHostsPeer1LosAngelesClientLiveTest extends ElasticStackClientLiveTest {
public ElasticHostsPeer1LosAngelesClientLiveTest() {
provider = "elastichosts-lax-p";
- bootDrive = "aee5589a-88c3-43ef-bb0a-9cab6e64192d";
}
+
}
diff --git a/providers/elastichosts-lon-b/pom.xml b/providers/elastichosts-lon-b/pom.xml
index 9f50c10..a0cf832 100644
--- a/providers/elastichosts-lon-b/pom.xml
+++ b/providers/elastichosts-lon-b/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.elastichosts-lon-b.endpoint>https://api.lon-b.elastichosts.com</test.elastichosts-lon-b.endpoint>
- <test.elastichosts-lon-b.apiversion>2.0</test.elastichosts-lon-b.apiversion>
+ <test.elastichosts-lon-b.api-version>2.0</test.elastichosts-lon-b.api-version>
+ <test.elastichosts-lon-b.build-version></test.elastichosts-lon-b.build-version>
<test.elastichosts-lon-b.identity>FIXME_IDENTITY</test.elastichosts-lon-b.identity>
<test.elastichosts-lon-b.credential>FIXME_CREDENTIAL</test.elastichosts-lon-b.credential>
<test.elastichosts-lon-b.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.elastichosts-lon-b.endpoint>${test.elastichosts-lon-b.endpoint}</test.elastichosts-lon-b.endpoint>
- <test.elastichosts-lon-b.apiversion>${test.elastichosts-lon-b.apiversion}</test.elastichosts-lon-b.apiversion>
+ <test.elastichosts-lon-b.api-version>${test.elastichosts-lon-b.api-version}</test.elastichosts-lon-b.api-version>
+ <test.elastichosts-lon-b.build-version>${test.elastichosts-lon-b.build-version}</test.elastichosts-lon-b.build-version>
<test.elastichosts-lon-b.identity>${test.elastichosts-lon-b.identity}</test.elastichosts-lon-b.identity>
<test.elastichosts-lon-b.credential>${test.elastichosts-lon-b.credential}</test.elastichosts-lon-b.credential>
<test.elastichosts-lon-b.image-id>${test.elastichosts-lon-b.image-id}</test.elastichosts-lon-b.image-id>
diff --git a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonClientLiveTest.java b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonClientLiveTest.java
index 906dc00..dc9bbc4 100644
--- a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonClientLiveTest.java
+++ b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "ElasticHostsBlueSquareLondonClientLiveTest")
public class ElasticHostsBlueSquareLondonClientLiveTest extends ElasticStackClientLiveTest {
public ElasticHostsBlueSquareLondonClientLiveTest() {
provider = "elastichosts-lon-b";
- bootDrive = "aee5589a-88c3-43ef-bb0a-9cab6e64192d";
}
}
diff --git a/providers/elastichosts-lon-p/pom.xml b/providers/elastichosts-lon-p/pom.xml
index 3f862a9..ee5b3d6 100644
--- a/providers/elastichosts-lon-p/pom.xml
+++ b/providers/elastichosts-lon-p/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.elastichosts-lon-p.endpoint>https://api.lon-p.elastichosts.com</test.elastichosts-lon-p.endpoint>
- <test.elastichosts-lon-p.apiversion>2.0</test.elastichosts-lon-p.apiversion>
+ <test.elastichosts-lon-p.api-version>2.0</test.elastichosts-lon-p.api-version>
+ <test.elastichosts-lon-p.build-version></test.elastichosts-lon-p.build-version>
<test.elastichosts-lon-p.identity>FIXME_IDENTITY</test.elastichosts-lon-p.identity>
<test.elastichosts-lon-p.credential>FIXME_CREDENTIAL</test.elastichosts-lon-p.credential>
<test.elastichosts-lon-p.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.elastichosts-lon-p.endpoint>${test.elastichosts-lon-p.endpoint}</test.elastichosts-lon-p.endpoint>
- <test.elastichosts-lon-p.apiversion>${test.elastichosts-lon-p.apiversion}</test.elastichosts-lon-p.apiversion>
+ <test.elastichosts-lon-p.api-version>${test.elastichosts-lon-p.api-version}</test.elastichosts-lon-p.api-version>
+ <test.elastichosts-lon-p.build-version>${test.elastichosts-lon-p.build-version}</test.elastichosts-lon-p.build-version>
<test.elastichosts-lon-p.identity>${test.elastichosts-lon-p.identity}</test.elastichosts-lon-p.identity>
<test.elastichosts-lon-p.credential>${test.elastichosts-lon-p.credential}</test.elastichosts-lon-p.credential>
<test.elastichosts-lon-p.image-id>${test.elastichosts-lon-p.image-id}</test.elastichosts-lon-p.image-id>
diff --git a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonClientLiveTest.java b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonClientLiveTest.java
index a0cbd87..7fe7895 100644
--- a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonClientLiveTest.java
+++ b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "ElasticHostsPeer1LondonClientLiveTest")
public class ElasticHostsPeer1LondonClientLiveTest extends ElasticStackClientLiveTest {
public ElasticHostsPeer1LondonClientLiveTest() {
provider = "elastichosts-lon-p";
- bootDrive = "aee5589a-88c3-43ef-bb0a-9cab6e64192d";
}
}
diff --git a/providers/elastichosts-sat-p/pom.xml b/providers/elastichosts-sat-p/pom.xml
index a60598a..47e5f04 100644
--- a/providers/elastichosts-sat-p/pom.xml
+++ b/providers/elastichosts-sat-p/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.elastichosts-sat-p.endpoint>https://api.sat-p.elastichosts.com</test.elastichosts-sat-p.endpoint>
- <test.elastichosts-sat-p.apiversion>2.0</test.elastichosts-sat-p.apiversion>
+ <test.elastichosts-sat-p.api-version>2.0</test.elastichosts-sat-p.api-version>
+ <test.elastichosts-sat-p.build-version></test.elastichosts-sat-p.build-version>
<test.elastichosts-sat-p.identity>FIXME_IDENTITY</test.elastichosts-sat-p.identity>
<test.elastichosts-sat-p.credential>FIXME_CREDENTIAL</test.elastichosts-sat-p.credential>
<test.elastichosts-sat-p.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.elastichosts-sat-p.endpoint>${test.elastichosts-sat-p.endpoint}</test.elastichosts-sat-p.endpoint>
- <test.elastichosts-sat-p.apiversion>${test.elastichosts-sat-p.apiversion}</test.elastichosts-sat-p.apiversion>
+ <test.elastichosts-sat-p.api-version>${test.elastichosts-sat-p.api-version}</test.elastichosts-sat-p.api-version>
+ <test.elastichosts-sat-p.build-version>${test.elastichosts-sat-p.build-version}</test.elastichosts-sat-p.build-version>
<test.elastichosts-sat-p.identity>${test.elastichosts-sat-p.identity}</test.elastichosts-sat-p.identity>
<test.elastichosts-sat-p.credential>${test.elastichosts-sat-p.credential}</test.elastichosts-sat-p.credential>
<test.elastichosts-sat-p.image-id>${test.elastichosts-sat-p.image-id}</test.elastichosts-sat-p.image-id>
diff --git a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioClientLiveTest.java b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioClientLiveTest.java
index ce90b54..d4cbc58 100644
--- a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioClientLiveTest.java
+++ b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "ElasticHostsPeer1SanAntonioClientLiveTest")
public class ElasticHostsPeer1SanAntonioClientLiveTest extends ElasticStackClientLiveTest {
public ElasticHostsPeer1SanAntonioClientLiveTest() {
provider = "elastichosts-sat-p";
- bootDrive = "aee5589a-88c3-43ef-bb0a-9cab6e64192d";
}
}
diff --git a/providers/elastichosts-tor-p/pom.xml b/providers/elastichosts-tor-p/pom.xml
index 92a1637..264d821 100644
--- a/providers/elastichosts-tor-p/pom.xml
+++ b/providers/elastichosts-tor-p/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.elastichosts-tor-p.endpoint>https://api.tor-p.elastichosts.com</test.elastichosts-tor-p.endpoint>
- <test.elastichosts-tor-p.apiversion>2.0</test.elastichosts-tor-p.apiversion>
+ <test.elastichosts-tor-p.api-version>2.0</test.elastichosts-tor-p.api-version>
+ <test.elastichosts-tor-p.build-version></test.elastichosts-tor-p.build-version>
<test.elastichosts-tor-p.identity>FIXME_IDENTITY</test.elastichosts-tor-p.identity>
<test.elastichosts-tor-p.credential>FIXME_CREDENTIAL</test.elastichosts-tor-p.credential>
<test.elastichosts-tor-p.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.elastichosts-tor-p.endpoint>${test.elastichosts-tor-p.endpoint}</test.elastichosts-tor-p.endpoint>
- <test.elastichosts-tor-p.apiversion>${test.elastichosts-tor-p.apiversion}</test.elastichosts-tor-p.apiversion>
+ <test.elastichosts-tor-p.api-version>${test.elastichosts-tor-p.api-version}</test.elastichosts-tor-p.api-version>
+ <test.elastichosts-tor-p.build-version>${test.elastichosts-tor-p.build-version}</test.elastichosts-tor-p.build-version>
<test.elastichosts-tor-p.identity>${test.elastichosts-tor-p.identity}</test.elastichosts-tor-p.identity>
<test.elastichosts-tor-p.credential>${test.elastichosts-tor-p.credential}</test.elastichosts-tor-p.credential>
<test.elastichosts-tor-p.image-id>${test.elastichosts-tor-p.image-id}</test.elastichosts-tor-p.image-id>
diff --git a/providers/elastichosts-tor-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1TorontoClientLiveTest.java b/providers/elastichosts-tor-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1TorontoClientLiveTest.java
index 568e2e1..aeeb524 100644
--- a/providers/elastichosts-tor-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1TorontoClientLiveTest.java
+++ b/providers/elastichosts-tor-p/src/test/java/org/jclouds/elastichosts/ElasticHostsPeer1TorontoClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "ElasticHostsPeer1TorontoClientLiveTest")
public class ElasticHostsPeer1TorontoClientLiveTest extends ElasticStackClientLiveTest {
public ElasticHostsPeer1TorontoClientLiveTest() {
provider = "elastichosts-tor-p";
- bootDrive = "aee5589a-88c3-43ef-bb0a-9cab6e64192d";
}
}
diff --git a/providers/eucalyptus-partnercloud-ec2/pom.xml b/providers/eucalyptus-partnercloud-ec2/pom.xml
index 4547ed1..e963fda 100644
--- a/providers/eucalyptus-partnercloud-ec2/pom.xml
+++ b/providers/eucalyptus-partnercloud-ec2/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.eucalyptus-partnercloud-ec2.endpoint>http://partnercloud.eucalyptus.com:8773/services/Eucalyptus</test.eucalyptus-partnercloud-ec2.endpoint>
- <test.eucalyptus-partnercloud-ec2.apiversion>2010-06-15</test.eucalyptus-partnercloud-ec2.apiversion>
+ <test.eucalyptus-partnercloud-ec2.api-version>2010-06-15</test.eucalyptus-partnercloud-ec2.api-version>
+ <test.eucalyptus-partnercloud-ec2.build-version></test.eucalyptus-partnercloud-ec2.build-version>
<test.eucalyptus-partnercloud-ec2.identity>FIXME_IDENTITY</test.eucalyptus-partnercloud-ec2.identity>
<test.eucalyptus-partnercloud-ec2.credential>FIXME_CREDENTIAL</test.eucalyptus-partnercloud-ec2.credential>
<test.eucalyptus-partnercloud-ec2.image-id />
@@ -115,7 +116,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.eucalyptus-partnercloud-ec2.endpoint>${test.eucalyptus-partnercloud-ec2.endpoint}</test.eucalyptus-partnercloud-ec2.endpoint>
- <test.eucalyptus-partnercloud-ec2.apiversion>${test.eucalyptus-partnercloud-ec2.apiversion}</test.eucalyptus-partnercloud-ec2.apiversion>
+ <test.eucalyptus-partnercloud-ec2.api-version>${test.eucalyptus-partnercloud-ec2.api-version}</test.eucalyptus-partnercloud-ec2.api-version>
+ <test.eucalyptus-partnercloud-ec2.build-version>${test.eucalyptus-partnercloud-ec2.build-version}</test.eucalyptus-partnercloud-ec2.build-version>
<test.eucalyptus-partnercloud-ec2.identity>${test.eucalyptus-partnercloud-ec2.identity}</test.eucalyptus-partnercloud-ec2.identity>
<test.eucalyptus-partnercloud-ec2.credential>${test.eucalyptus-partnercloud-ec2.credential}</test.eucalyptus-partnercloud-ec2.credential>
<test.eucalyptus-partnercloud-ec2.image-id>${test.eucalyptus-partnercloud-ec2.image-id}</test.eucalyptus-partnercloud-ec2.image-id>
diff --git a/providers/eucalyptus-partnercloud-s3/pom.xml b/providers/eucalyptus-partnercloud-s3/pom.xml
index 2aba40b..40e5723 100644
--- a/providers/eucalyptus-partnercloud-s3/pom.xml
+++ b/providers/eucalyptus-partnercloud-s3/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.epc.blobstore.EucalyptusPartnerCloudWalrusTestInitializer</test.initializer>
<test.eucalyptus-partnercloud-s3.endpoint>http://partnercloud.eucalyptus.com:8773/services/Walrus</test.eucalyptus-partnercloud-s3.endpoint>
- <test.eucalyptus-partnercloud-s3.apiversion>2006-03-01</test.eucalyptus-partnercloud-s3.apiversion>
+ <test.eucalyptus-partnercloud-s3.api-version>2006-03-01</test.eucalyptus-partnercloud-s3.api-version>
+ <test.eucalyptus-partnercloud-s3.build-version></test.eucalyptus-partnercloud-s3.build-version>
<test.eucalyptus-partnercloud-s3.identity>FIXME_IDENTITY</test.eucalyptus-partnercloud-s3.identity>
<test.eucalyptus-partnercloud-s3.credential>FIXME_CREDENTIAL</test.eucalyptus-partnercloud-s3.credential>
<test.blobstore.container-count>15</test.blobstore.container-count>
@@ -110,7 +111,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.eucalyptus-partnercloud-s3.endpoint>${test.eucalyptus-partnercloud-s3.endpoint}</test.eucalyptus-partnercloud-s3.endpoint>
- <test.eucalyptus-partnercloud-s3.apiversion>${test.eucalyptus-partnercloud-s3.apiversion}</test.eucalyptus-partnercloud-s3.apiversion>
+ <test.eucalyptus-partnercloud-s3.api-version>${test.eucalyptus-partnercloud-s3.api-version}</test.eucalyptus-partnercloud-s3.api-version>
+ <test.eucalyptus-partnercloud-s3.build-version>${test.eucalyptus-partnercloud-s3.build-version}</test.eucalyptus-partnercloud-s3.build-version>
<test.eucalyptus-partnercloud-s3.identity>${test.eucalyptus-partnercloud-s3.identity}</test.eucalyptus-partnercloud-s3.identity>
<test.eucalyptus-partnercloud-s3.credential>${test.eucalyptus-partnercloud-s3.credential}</test.eucalyptus-partnercloud-s3.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/go2cloud-jhb1/pom.xml b/providers/go2cloud-jhb1/pom.xml
index c3a212f..4efa579 100644
--- a/providers/go2cloud-jhb1/pom.xml
+++ b/providers/go2cloud-jhb1/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.go2cloud-jhb1.endpoint>http://api.jhb1.go2cloud.co.za</test.go2cloud-jhb1.endpoint>
- <test.go2cloud-jhb1.apiversion>2.0</test.go2cloud-jhb1.apiversion>
+ <test.go2cloud-jhb1.api-version>2.0</test.go2cloud-jhb1.api-version>
+ <test.go2cloud-jhb1.build-version></test.go2cloud-jhb1.build-version>
<test.go2cloud-jhb1.identity>FIXME_IDENTITY</test.go2cloud-jhb1.identity>
<test.go2cloud-jhb1.credential>FIXME_CREDENTIAL</test.go2cloud-jhb1.credential>
<test.go2cloud-jhb1.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.go2cloud-jhb1.endpoint>${test.go2cloud-jhb1.endpoint}</test.go2cloud-jhb1.endpoint>
- <test.go2cloud-jhb1.apiversion>${test.go2cloud-jhb1.apiversion}</test.go2cloud-jhb1.apiversion>
+ <test.go2cloud-jhb1.api-version>${test.go2cloud-jhb1.api-version}</test.go2cloud-jhb1.api-version>
+ <test.go2cloud-jhb1.build-version>${test.go2cloud-jhb1.build-version}</test.go2cloud-jhb1.build-version>
<test.go2cloud-jhb1.identity>${test.go2cloud-jhb1.identity}</test.go2cloud-jhb1.identity>
<test.go2cloud-jhb1.credential>${test.go2cloud-jhb1.credential}</test.go2cloud-jhb1.credential>
<test.go2cloud-jhb1.image-id>${test.go2cloud-jhb1.image-id}</test.go2cloud-jhb1.image-id>
diff --git a/providers/go2cloud-jhb1/src/test/java/org/jclouds/go2cloud/Go2CloudJohannesburg1ClientLiveTest.java b/providers/go2cloud-jhb1/src/test/java/org/jclouds/go2cloud/Go2CloudJohannesburg1ClientLiveTest.java
index 9d6d9c5..cffecba 100644
--- a/providers/go2cloud-jhb1/src/test/java/org/jclouds/go2cloud/Go2CloudJohannesburg1ClientLiveTest.java
+++ b/providers/go2cloud-jhb1/src/test/java/org/jclouds/go2cloud/Go2CloudJohannesburg1ClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", singleThreaded = true)
+@Test(groups = "live", singleThreaded = true, testName = "Go2CloudJohannesburg1ClientLiveTest")
public class Go2CloudJohannesburg1ClientLiveTest extends ElasticStackClientLiveTest {
public Go2CloudJohannesburg1ClientLiveTest() {
provider = "go2cloud-jhb1";
- bootDrive = "14c88d27-1f5e-4ad5-9f3a-28e5d2282f61";
}
}
diff --git a/providers/gogrid/pom.xml b/providers/gogrid/pom.xml
index 95396e6..cac7385 100644
--- a/providers/gogrid/pom.xml
+++ b/providers/gogrid/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.gogrid.endpoint>https://api.gogrid.com/api</test.gogrid.endpoint>
- <test.gogrid.apiversion>1.5</test.gogrid.apiversion>
+ <test.gogrid.api-version>1.5</test.gogrid.api-version>
+ <test.gogrid.build-version></test.gogrid.build-version>
<test.gogrid.identity>FIXME</test.gogrid.identity>
<test.gogrid.credential>FIXME</test.gogrid.credential>
<test.gogrid.image-id />
@@ -93,7 +94,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.gogrid.endpoint>${test.gogrid.endpoint}</test.gogrid.endpoint>
- <test.gogrid.apiversion>${test.gogrid.apiversion}</test.gogrid.apiversion>
+ <test.gogrid.api-version>${test.gogrid.api-version}</test.gogrid.api-version>
+ <test.gogrid.build-version>${test.gogrid.build-version}</test.gogrid.build-version>
<test.gogrid.identity>${test.gogrid.identity}</test.gogrid.identity>
<test.gogrid.credential>${test.gogrid.credential}</test.gogrid.credential>
<test.gogrid.image-id>${test.gogrid.image-id}</test.gogrid.image-id>
diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java
index ae0abcc..90bfcda 100644
--- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java
+++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java
@@ -17,7 +17,6 @@
* under the License.
*/
package org.jclouds.gogrid.compute.functions;
-
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
@@ -38,6 +37,7 @@
import org.jclouds.domain.Location;
import org.jclouds.gogrid.domain.Server;
import org.jclouds.gogrid.domain.ServerState;
+import org.jclouds.location.predicates.LocationPredicates;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
@@ -57,7 +57,7 @@
private final Map<ServerState, NodeState> serverStateToNodeState;
private final Supplier<Set<? extends Image>> images;
private final Supplier<Set<? extends Hardware>> hardwares;
- private final Supplier<Map<String, ? extends Location>> locations;
+ private final Supplier<Set<? extends Location>> locations;
static class FindImageForServer implements Predicate<Image> {
private final Server instance;
@@ -92,7 +92,7 @@
@Inject
ServerToNodeMetadata(Map<ServerState, NodeState> serverStateToNodeState,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares,
- Supplier<Map<String, ? extends Location>> locations) {
+ @Memoized Supplier<Set<? extends Location>> locations) {
this.serverStateToNodeState = checkNotNull(serverStateToNodeState, "serverStateToNodeState");
this.images = checkNotNull(images, "images");
this.hardwares = checkNotNull(hardwares, "hardwares");
@@ -104,7 +104,8 @@
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.ids(from.getId() + "");
builder.name(from.getName());
- builder.location(locations.get().get(from.getDatacenter().getId() + ""));
+ Location location = Iterables.find(locations.get(), LocationPredicates.idEquals(from.getDatacenter().getId() + ""));
+ builder.location(location);
builder.group(parseGroupFromName(from.getName()));
builder.hardware(parseHardware(from));
builder.imageId(from.getImage().getId() + "");
diff --git a/providers/gogrid/src/test/java/org/jclouds/gogrid/GoGridLiveTestDisabled.java b/providers/gogrid/src/test/java/org/jclouds/gogrid/GoGridLiveTestDisabled.java
index eca8e81..8648076 100644
--- a/providers/gogrid/src/test/java/org/jclouds/gogrid/GoGridLiveTestDisabled.java
+++ b/providers/gogrid/src/test/java/org/jclouds/gogrid/GoGridLiveTestDisabled.java
@@ -35,9 +35,7 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import org.jclouds.javax.annotation.Nullable;
-
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.domain.Credentials;
import org.jclouds.gogrid.domain.Ip;
@@ -56,6 +54,7 @@
import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted;
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
+import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
@@ -81,9 +80,11 @@
*
* @author Oleksiy Yarmula
*/
-// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
-@Test(enabled = false, groups = "live", testName = "GoGridLiveTestDisabled")
-public class GoGridLiveTestDisabled {
+@Test(enabled = false, groups = "live", singleThreaded = true, testName = "GoGridLiveTestDisabled")
+public class GoGridLiveTestDisabled extends BaseVersionedServiceLiveTest {
+ public GoGridLiveTestDisabled() {
+ provider = "gogrid";
+ }
private GoGridClient client;
@@ -96,32 +97,6 @@
private List<String> loadBalancersToDeleteAfterTest = new ArrayList<String>();
private RestContext<GoGridClient, GoGridAsyncClient> context;
- protected String provider = "gogrid";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/providers/gogrid/src/test/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadataTest.java b/providers/gogrid/src/test/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadataTest.java
index f9cc489..a864541 100644
--- a/providers/gogrid/src/test/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadataTest.java
+++ b/providers/gogrid/src/test/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadataTest.java
@@ -44,7 +44,6 @@
import org.testng.annotations.Test;
import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
@@ -73,8 +72,8 @@
expect(serverStateToNodeState.get(ServerState.ON)).andReturn(NodeState.RUNNING);
Location location = new LocationBuilder().scope(LocationScope.ZONE).id("1").description("US-West-1").build();
- Map<String, ? extends Location> locations = ImmutableMap.<String, Location> of("1", location);
-
+ Set< ? extends Location> locations = ImmutableSet.< Location> of( location);
+
expect(server.getIp()).andReturn(new Ip("127.0.0.1"));
ServerImage image = createMock(ServerImage.class);
@@ -94,7 +93,7 @@
ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, Suppliers
.<Set<? extends Image>> ofInstance(images), Suppliers
.<Set<? extends Hardware>> ofInstance(GoGridHardwareSupplier.H_ALL), Suppliers
- .<Map<String, ? extends Location>> ofInstance(locations));
+ .<Set<? extends Location>> ofInstance(locations));
NodeMetadata metadata = parser.apply(server);
assertEquals(metadata.getLocation(), location);
diff --git a/providers/gogrid/src/test/java/org/jclouds/gogrid/services/BaseGoGridClientLiveTest.java b/providers/gogrid/src/test/java/org/jclouds/gogrid/services/BaseGoGridClientLiveTest.java
index 3a7c7c9..9ca9e9b 100644
--- a/providers/gogrid/src/test/java/org/jclouds/gogrid/services/BaseGoGridClientLiveTest.java
+++ b/providers/gogrid/src/test/java/org/jclouds/gogrid/services/BaseGoGridClientLiveTest.java
@@ -18,10 +18,9 @@
*/
package org.jclouds.gogrid.services;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.util.Properties;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.gogrid.GoGridAsyncClient;
@@ -41,36 +40,14 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class BaseGoGridClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "BaseGoGridClientLiveTest")
+public class BaseGoGridClientLiveTest extends BaseVersionedServiceLiveTest {
+ public BaseGoGridClientLiveTest() {
+ provider = "gogrid";
+ }
protected RestContext<GoGridClient, GoGridAsyncClient> restContext;
- protected String provider = "gogrid";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected ComputeServiceContext context;
- protected String prefix = System.getProperty("user.name");
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/providers/greenhousedata-element-vcloud/pom.xml b/providers/greenhousedata-element-vcloud/pom.xml
index f1ceac2..8b9c4d1 100644
--- a/providers/greenhousedata-element-vcloud/pom.xml
+++ b/providers/greenhousedata-element-vcloud/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.greenhousedata-element-vcloud.endpoint>https://mycloud.greenhousedata.com/api</test.greenhousedata-element-vcloud.endpoint>
- <test.greenhousedata-element-vcloud.apiversion>1.0</test.greenhousedata-element-vcloud.apiversion>
+ <test.greenhousedata-element-vcloud.api-version>1.0</test.greenhousedata-element-vcloud.api-version>
+ <test.greenhousedata-element-vcloud.build-version></test.greenhousedata-element-vcloud.build-version>
<test.greenhousedata-element-vcloud.identity>FIXME_IDENTITY</test.greenhousedata-element-vcloud.identity>
<test.greenhousedata-element-vcloud.credential>FIXME_CREDENTIAL</test.greenhousedata-element-vcloud.credential>
<test.greenhousedata-element-vcloud.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.greenhousedata-element-vcloud.endpoint>${test.greenhousedata-element-vcloud.endpoint}</test.greenhousedata-element-vcloud.endpoint>
- <test.greenhousedata-element-vcloud.apiversion>${test.greenhousedata-element-vcloud.apiversion}</test.greenhousedata-element-vcloud.apiversion>
+ <test.greenhousedata-element-vcloud.api-version>${test.greenhousedata-element-vcloud.api-version}</test.greenhousedata-element-vcloud.api-version>
+ <test.greenhousedata-element-vcloud.build-version>${test.greenhousedata-element-vcloud.build-version}</test.greenhousedata-element-vcloud.build-version>
<test.greenhousedata-element-vcloud.identity>${test.greenhousedata-element-vcloud.identity}</test.greenhousedata-element-vcloud.identity>
<test.greenhousedata-element-vcloud.credential>${test.greenhousedata-element-vcloud.credential}</test.greenhousedata-element-vcloud.credential>
<test.greenhousedata-element-vcloud.image-id>${test.greenhousedata-element-vcloud.image-id}</test.greenhousedata-element-vcloud.image-id>
diff --git a/providers/hpcloud-objectstorage-lvs/pom.xml b/providers/hpcloud-objectstorage-lvs/pom.xml
index be4778e..b287a94 100644
--- a/providers/hpcloud-objectstorage-lvs/pom.xml
+++ b/providers/hpcloud-objectstorage-lvs/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.hpcloud.objectstorage.lvs.blobstore.integration.HPCloudObjectStorageLasVegasTestInitializer</test.initializer>
<test.hpcloud-objectstorage-lvs.endpoint>https://region-a.geo-1.objects.hpcloudsvc.com/auth</test.hpcloud-objectstorage-lvs.endpoint>
- <test.hpcloud-objectstorage-lvs.apiversion>1.0</test.hpcloud-objectstorage-lvs.apiversion>
+ <test.hpcloud-objectstorage-lvs.api-version>1.0</test.hpcloud-objectstorage-lvs.api-version>
+ <test.hpcloud-objectstorage-lvs.build-version></test.hpcloud-objectstorage-lvs.build-version>
<test.hpcloud-objectstorage-lvs.identity>FIXME_IDENTITY</test.hpcloud-objectstorage-lvs.identity>
<test.hpcloud-objectstorage-lvs.credential>FIXME_CREDENTIAL</test.hpcloud-objectstorage-lvs.credential>
</properties>
@@ -111,8 +112,12 @@
<value>${test.hpcloud-objectstorage-lvs.endpoint}</value>
</property>
<property>
- <name>test.hpcloud-objectstorage-lvs.apiversion</name>
- <value>${test.hpcloud-objectstorage-lvs.apiversion}</value>
+ <name>test.hpcloud-objectstorage-lvs.api-version</name>
+ <value>${test.hpcloud-objectstorage-lvs.api-version}</value>
+ </property>
+ <property>
+ <name>test.hpcloud-objectstorage-lvs.build-version</name>
+ <value>${test.hpcloud-objectstorage-lvs.build-version}</value>
</property>
<property>
<name>test.hpcloud-objectstorage-lvs.identity</name>
diff --git a/providers/ninefold-compute/pom.xml b/providers/ninefold-compute/pom.xml
index 6ed69b9..e033a33 100644
--- a/providers/ninefold-compute/pom.xml
+++ b/providers/ninefold-compute/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.ninefold-compute.endpoint>https://api.ninefold.com/compute/v1.0/</test.ninefold-compute.endpoint>
- <test.ninefold-compute.apiversion>2.2.12</test.ninefold-compute.apiversion>
+ <test.ninefold-compute.api-version>2.2.12</test.ninefold-compute.api-version>
+ <test.ninefold-compute.build-version></test.ninefold-compute.build-version>
<test.ninefold-compute.identity>FIXME_IDENTITY</test.ninefold-compute.identity>
<test.ninefold-compute.credential>FIXME_CREDENTIAL</test.ninefold-compute.credential>
<test.ninefold-compute.image-id>1215</test.ninefold-compute.image-id>
@@ -103,7 +104,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.ninefold-compute.endpoint>${test.ninefold-compute.endpoint}</test.ninefold-compute.endpoint>
- <test.ninefold-compute.apiversion>${test.ninefold-compute.apiversion}</test.ninefold-compute.apiversion>
+ <test.ninefold-compute.api-version>${test.ninefold-compute.api-version}</test.ninefold-compute.api-version>
+ <test.ninefold-compute.build-version>${test.ninefold-compute.build-version}</test.ninefold-compute.build-version>
<test.ninefold-compute.identity>${test.ninefold-compute.identity}</test.ninefold-compute.identity>
<test.ninefold-compute.credential>${test.ninefold-compute.credential}</test.ninefold-compute.credential>
<test.ninefold-compute.image-id>${test.ninefold-compute.image-id}</test.ninefold-compute.image-id>
diff --git a/providers/ninefold-storage/pom.xml b/providers/ninefold-storage/pom.xml
index f6e4623..4c5581b 100644
--- a/providers/ninefold-storage/pom.xml
+++ b/providers/ninefold-storage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.ninefold.storage.blobstore.integration.NinefoldStorageTestInitializer</test.initializer>
<test.ninefold-storage.endpoint>http://onlinestorage.ninefold.com</test.ninefold-storage.endpoint>
- <test.ninefold-storage.apiversion>1.4.0</test.ninefold-storage.apiversion>
+ <test.ninefold-storage.api-version>1.4.0</test.ninefold-storage.api-version>
+ <test.ninefold-storage.build-version></test.ninefold-storage.build-version>
<test.ninefold-storage.identity>FIXME_IDENTITY</test.ninefold-storage.identity>
<test.ninefold-storage.credential>FIXME_CREDENTIAL</test.ninefold-storage.credential>
</properties>
@@ -101,7 +102,8 @@
<configuration>
<systemPropertyVariables>
<test.ninefold-storage.endpoint>${test.ninefold-storage.endpoint}</test.ninefold-storage.endpoint>
- <test.ninefold-storage.apiversion>${test.ninefold-storage.apiversion}</test.ninefold-storage.apiversion>
+ <test.ninefold-storage.api-version>${test.ninefold-storage.api-version}</test.ninefold-storage.api-version>
+ <test.ninefold-storage.build-version>${test.ninefold-storage.build-version}</test.ninefold-storage.build-version>
<test.ninefold-storage.identity>${test.ninefold-storage.identity}</test.ninefold-storage.identity>
<test.ninefold-storage.credential>${test.ninefold-storage.credential}</test.ninefold-storage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/openhosting-east1/pom.xml b/providers/openhosting-east1/pom.xml
index 9be8296..8abd04a 100644
--- a/providers/openhosting-east1/pom.xml
+++ b/providers/openhosting-east1/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.openhosting-east1.endpoint>https://api.east1.openhosting.com</test.openhosting-east1.endpoint>
- <test.openhosting-east1.apiversion>2.0</test.openhosting-east1.apiversion>
+ <test.openhosting-east1.api-version>2.0</test.openhosting-east1.api-version>
+ <test.openhosting-east1.build-version></test.openhosting-east1.build-version>
<test.openhosting-east1.identity>FIXME_IDENTITY</test.openhosting-east1.identity>
<test.openhosting-east1.credential>FIXME_CREDENTIAL</test.openhosting-east1.credential>
<test.openhosting-east1.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.openhosting-east1.endpoint>${test.openhosting-east1.endpoint}</test.openhosting-east1.endpoint>
- <test.openhosting-east1.apiversion>${test.openhosting-east1.apiversion}</test.openhosting-east1.apiversion>
+ <test.openhosting-east1.api-version>${test.openhosting-east1.api-version}</test.openhosting-east1.api-version>
+ <test.openhosting-east1.build-version>${test.openhosting-east1.build-version}</test.openhosting-east1.build-version>
<test.openhosting-east1.identity>${test.openhosting-east1.identity}</test.openhosting-east1.identity>
<test.openhosting-east1.credential>${test.openhosting-east1.credential}</test.openhosting-east1.credential>
<test.openhosting-east1.image-id>${test.openhosting-east1.image-id}</test.openhosting-east1.image-id>
diff --git a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/OpenHostingEast1ClientLiveTest.java b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/OpenHostingEast1ClientLiveTest.java
index fef04bc..c1924e3 100644
--- a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/OpenHostingEast1ClientLiveTest.java
+++ b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/OpenHostingEast1ClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "OpenHostingEast1ClientLiveTest")
public class OpenHostingEast1ClientLiveTest extends ElasticStackClientLiveTest {
public OpenHostingEast1ClientLiveTest() {
provider = "openhosting-east1";
- bootDrive = "8023b089-7b0e-4fcb-8016-01e82f2a9716";
}
}
diff --git a/providers/rimuhosting/pom.xml b/providers/rimuhosting/pom.xml
index 5066876..07e2d84 100644
--- a/providers/rimuhosting/pom.xml
+++ b/providers/rimuhosting/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.rimuhosting.endpoint>https://api.rimuhosting.com/r</test.rimuhosting.endpoint>
- <test.rimuhosting.apiversion>1.0</test.rimuhosting.apiversion>
+ <test.rimuhosting.api-version>1.0</test.rimuhosting.api-version>
+ <test.rimuhosting.build-version></test.rimuhosting.build-version>
<test.rimuhosting.identity>FIXME</test.rimuhosting.identity>
<test.rimuhosting.image-id />
</properties>
@@ -101,7 +102,8 @@
<configuration>
<systemPropertyVariables>
<test.rimuhosting.endpoint>${test.rimuhosting.endpoint}</test.rimuhosting.endpoint>
- <test.rimuhosting.apiversion>${test.rimuhosting.apiversion}</test.rimuhosting.apiversion>
+ <test.rimuhosting.api-version>${test.rimuhosting.api-version}</test.rimuhosting.api-version>
+ <test.rimuhosting.build-version>${test.rimuhosting.build-version}</test.rimuhosting.build-version>
<test.rimuhosting.identity>${test.rimuhosting.identity}</test.rimuhosting.identity>
<test.rimuhosting.image-id>${test.rimuhosting.image-id}</test.rimuhosting.image-id>
</systemPropertyVariables>
diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java
index fff7149..f9142d5 100644
--- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java
+++ b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java
@@ -26,8 +26,6 @@
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
-import org.jclouds.rest.RestContext;
-import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.compute.functions.ServerToNodeMetadata;
@@ -60,9 +58,6 @@
bind(new TypeLiteral<ComputeServiceContext>() {
}).to(new TypeLiteral<ComputeServiceContextImpl<RimuHostingClient, RimuHostingAsyncClient>>() {
}).in(Scopes.SINGLETON);
- bind(new TypeLiteral<RestContext<RimuHostingClient, RimuHostingAsyncClient>>() {
- }).to(new TypeLiteral<RestContextImpl<RimuHostingClient, RimuHostingAsyncClient>>() {
- }).in(Scopes.SINGLETON);
bind(new TypeLiteral<Function<Server, Iterable<String>>>() {
}).to(ServerToPublicAddresses.class);
diff --git a/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/RimuHostingClientLiveTest.java b/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/RimuHostingClientLiveTest.java
index 818e14e..e63a412 100644
--- a/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/RimuHostingClientLiveTest.java
+++ b/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/RimuHostingClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.rimuhosting.miro;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -26,7 +25,7 @@
import java.util.Properties;
import java.util.Set;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
@@ -47,41 +46,21 @@
*
* @author Ivan Meredith
*/
-@Test(groups = "live")
-public class RimuHostingClientLiveTest {
-
+@Test(groups = "live", singleThreaded = true, testName = "RimuHostingClientLiveTest")
+public class RimuHostingClientLiveTest extends BaseVersionedServiceLiveTest {
+ public RimuHostingClientLiveTest() {
+ provider = "rimuhosting";
+ }
+
private RimuHostingClient connection;
private RestContext<RimuHostingClient, RimuHostingAsyncClient> context;
- protected String provider = "rimuhosting";
- protected String identity;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
- this.context = new RestContextFactory().createContext("rimuhosting", ImmutableSet
+ this.context = new RestContextFactory().createContext(provider, ImmutableSet
.<Module> of(new Log4JLoggingModule()), overrides);
this.connection = context.getApi();
diff --git a/providers/savvis-symphonyvpdc/pom.xml b/providers/savvis-symphonyvpdc/pom.xml
index af73682..2a74762 100644
--- a/providers/savvis-symphonyvpdc/pom.xml
+++ b/providers/savvis-symphonyvpdc/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.savvis-symphonyvpdc.endpoint>https://api.symphonyvpdc.savvis.net/vpdc</test.savvis-symphonyvpdc.endpoint>
- <test.savvis-symphonyvpdc.apiversion>1.0</test.savvis-symphonyvpdc.apiversion>
+ <test.savvis-symphonyvpdc.api-version>1.0</test.savvis-symphonyvpdc.api-version>
+ <test.savvis-symphonyvpdc.build-version></test.savvis-symphonyvpdc.build-version>
<test.savvis-symphonyvpdc.identity>FIXME</test.savvis-symphonyvpdc.identity>
<test.savvis-symphonyvpdc.credential>FIXME</test.savvis-symphonyvpdc.credential>
<test.savvis-symphonyvpdc.image-id />
@@ -114,7 +115,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.savvis-symphonyvpdc.endpoint>${test.savvis-symphonyvpdc.endpoint}</test.savvis-symphonyvpdc.endpoint>
- <test.savvis-symphonyvpdc.apiversion>${test.savvis-symphonyvpdc.apiversion}</test.savvis-symphonyvpdc.apiversion>
+ <test.savvis-symphonyvpdc.api-version>${test.savvis-symphonyvpdc.api-version}</test.savvis-symphonyvpdc.api-version>
+ <test.savvis-symphonyvpdc.build-version>${test.savvis-symphonyvpdc.build-version}</test.savvis-symphonyvpdc.build-version>
<test.savvis-symphonyvpdc.identity>${test.savvis-symphonyvpdc.identity}</test.savvis-symphonyvpdc.identity>
<test.savvis-symphonyvpdc.credential>${test.savvis-symphonyvpdc.credential}</test.savvis-symphonyvpdc.credential>
<test.savvis-symphonyvpdc.image-id>${test.savvis-symphonyvpdc.image-id}</test.savvis-symphonyvpdc.image-id>
diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java
index 3df5493..693b1b2 100644
--- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java
+++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/BaseVPDCClientLiveTest.java
@@ -23,7 +23,7 @@
import java.util.Properties;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@@ -46,42 +46,28 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class BaseVPDCClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "BaseVPDCClientLiveTest")
+public class BaseVPDCClientLiveTest extends BaseVersionedServiceLiveTest {
+ public BaseVPDCClientLiveTest() {
+ provider = "savvis-symphonyvpdc";
+ }
protected RestContext<VPDCClient, VPDCAsyncClient> restContext;
- protected String provider = "savvis-symphonyvpdc";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
protected ComputeServiceContext context;
protected String email;
protected RetryablePredicate<String> taskTester;
- protected String prefix = System.getProperty("user.name");
+ @Override
protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
+ super.setupCredentials();
email = checkNotNull(System.getProperty("test." + VPDCConstants.PROPERTY_VPDC_VDC_EMAIL), "test."
+ VPDCConstants.PROPERTY_VPDC_VDC_EMAIL);
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
}
-
+
+ @Override
protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
+ Properties overrides = super.setupProperties();
overrides.setProperty(VPDCConstants.PROPERTY_VPDC_VDC_EMAIL, email);
- if (endpoint != null)
- overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
- // TODO savvis uses untrusted certificates, remove these once savvis fixes the issue
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
return overrides;
}
diff --git a/providers/serverlove-z1-man/pom.xml b/providers/serverlove-z1-man/pom.xml
index cd90b99..9de7ece 100644
--- a/providers/serverlove-z1-man/pom.xml
+++ b/providers/serverlove-z1-man/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.serverlove-z1-man.endpoint>https://api.z1-man.serverlove.com</test.serverlove-z1-man.endpoint>
- <test.serverlove-z1-man.apiversion>1.0</test.serverlove-z1-man.apiversion>
+ <test.serverlove-z1-man.api-version>1.0</test.serverlove-z1-man.api-version>
+ <test.serverlove-z1-man.build-version></test.serverlove-z1-man.build-version>
<test.serverlove-z1-man.identity>FIXME_IDENTITY</test.serverlove-z1-man.identity>
<test.serverlove-z1-man.credential>FIXME_CREDENTIAL</test.serverlove-z1-man.credential>
<test.serverlove-z1-man.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.serverlove-z1-man.endpoint>${test.serverlove-z1-man.endpoint}</test.serverlove-z1-man.endpoint>
- <test.serverlove-z1-man.apiversion>${test.serverlove-z1-man.apiversion}</test.serverlove-z1-man.apiversion>
+ <test.serverlove-z1-man.api-version>${test.serverlove-z1-man.api-version}</test.serverlove-z1-man.api-version>
+ <test.serverlove-z1-man.build-version>${test.serverlove-z1-man.build-version}</test.serverlove-z1-man.build-version>
<test.serverlove-z1-man.identity>${test.serverlove-z1-man.identity}</test.serverlove-z1-man.identity>
<test.serverlove-z1-man.credential>${test.serverlove-z1-man.credential}</test.serverlove-z1-man.credential>
<test.serverlove-z1-man.image-id>${test.serverlove-z1-man.image-id}</test.serverlove-z1-man.image-id>
diff --git a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/ServerloveManchesterClientLiveTest.java b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/ServerloveManchesterClientLiveTest.java
index fb76ef7..e7f1ced 100644
--- a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/ServerloveManchesterClientLiveTest.java
+++ b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/ServerloveManchesterClientLiveTest.java
@@ -27,11 +27,10 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", singleThreaded = true)
+@Test(groups = "live", singleThreaded = true, testName = "ServerloveManchesterClientLiveTest")
public class ServerloveManchesterClientLiveTest extends ElasticStackClientLiveTest {
public ServerloveManchesterClientLiveTest() {
provider = "serverlove-z1-man";
- bootDrive = "574a3921-2926-4a61-bdd9-8d9282b32810";
}
@Override
diff --git a/providers/skalicloud-sdg-my/pom.xml b/providers/skalicloud-sdg-my/pom.xml
index 659a0a5..915903c 100644
--- a/providers/skalicloud-sdg-my/pom.xml
+++ b/providers/skalicloud-sdg-my/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.skalicloud-sdg-my.endpoint>https://api.sdg-my.skalicloud.com</test.skalicloud-sdg-my.endpoint>
- <test.skalicloud-sdg-my.apiversion>1.0</test.skalicloud-sdg-my.apiversion>
+ <test.skalicloud-sdg-my.api-version>1.0</test.skalicloud-sdg-my.api-version>
+ <test.skalicloud-sdg-my.build-version></test.skalicloud-sdg-my.build-version>
<test.skalicloud-sdg-my.identity>FIXME_IDENTITY</test.skalicloud-sdg-my.identity>
<test.skalicloud-sdg-my.credential>FIXME_CREDENTIAL</test.skalicloud-sdg-my.credential>
<test.skalicloud-sdg-my.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.skalicloud-sdg-my.endpoint>${test.skalicloud-sdg-my.endpoint}</test.skalicloud-sdg-my.endpoint>
- <test.skalicloud-sdg-my.apiversion>${test.skalicloud-sdg-my.apiversion}</test.skalicloud-sdg-my.apiversion>
+ <test.skalicloud-sdg-my.api-version>${test.skalicloud-sdg-my.api-version}</test.skalicloud-sdg-my.api-version>
+ <test.skalicloud-sdg-my.build-version>${test.skalicloud-sdg-my.build-version}</test.skalicloud-sdg-my.build-version>
<test.skalicloud-sdg-my.identity>${test.skalicloud-sdg-my.identity}</test.skalicloud-sdg-my.identity>
<test.skalicloud-sdg-my.credential>${test.skalicloud-sdg-my.credential}</test.skalicloud-sdg-my.credential>
<test.skalicloud-sdg-my.image-id>${test.skalicloud-sdg-my.image-id}</test.skalicloud-sdg-my.image-id>
diff --git a/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/SkaliCloudMalaysiaClientLiveTest.java b/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/SkaliCloudMalaysiaClientLiveTest.java
index 01bd6b3..63e6b9b 100644
--- a/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/SkaliCloudMalaysiaClientLiveTest.java
+++ b/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/SkaliCloudMalaysiaClientLiveTest.java
@@ -25,10 +25,9 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
+@Test(groups = "live", singleThreaded = true, testName = "SkaliCloudMalaysiaClientLiveTest")
public class SkaliCloudMalaysiaClientLiveTest extends ElasticStackClientLiveTest {
public SkaliCloudMalaysiaClientLiveTest() {
provider = "skalicloud-sdg-my";
- bootDrive = "3051699a-a536-4220-aeb5-67f2ec101a09";
}
}
diff --git a/providers/slicehost/pom.xml b/providers/slicehost/pom.xml
index 2ad2b01..6aa49fc 100644
--- a/providers/slicehost/pom.xml
+++ b/providers/slicehost/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.slicehost.endpoint>https://api.slicehost.com</test.slicehost.endpoint>
- <test.slicehost.apiversion>1.4.1.1</test.slicehost.apiversion>
+ <test.slicehost.api-version>1.4.1.1</test.slicehost.api-version>
+ <test.slicehost.build-version></test.slicehost.build-version>
<test.slicehost.identity>FIXME</test.slicehost.identity>
<test.slicehost.image-id />
</properties>
@@ -93,7 +94,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.slicehost.endpoint>${test.slicehost.endpoint}</test.slicehost.endpoint>
- <test.slicehost.apiversion>${test.slicehost.apiversion}</test.slicehost.apiversion>
+ <test.slicehost.api-version>${test.slicehost.api-version}</test.slicehost.api-version>
+ <test.slicehost.build-version>${test.slicehost.build-version}</test.slicehost.build-version>
<test.slicehost.identity>${test.slicehost.identity}</test.slicehost.identity>
<test.slicehost.image-id>${test.slicehost.image-id}</test.slicehost.image-id>
</systemPropertyVariables>
diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java
index 304302c..34fe05e 100644
--- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java
+++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java
@@ -1,3 +1,21 @@
+/**
+ * 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.slicehost.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/providers/slicehost/src/test/java/org/jclouds/slicehost/SlicehostClientLiveTest.java b/providers/slicehost/src/test/java/org/jclouds/slicehost/SlicehostClientLiveTest.java
index 0f371cc..b15f7fb 100644
--- a/providers/slicehost/src/test/java/org/jclouds/slicehost/SlicehostClientLiveTest.java
+++ b/providers/slicehost/src/test/java/org/jclouds/slicehost/SlicehostClientLiveTest.java
@@ -18,7 +18,6 @@
*/
package org.jclouds.slicehost;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@@ -30,7 +29,7 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payloads;
@@ -60,36 +59,16 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class SlicehostClientLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "SlicehostClientLiveTest")
+public class SlicehostClientLiveTest extends BaseVersionedServiceLiveTest {
+ public SlicehostClientLiveTest() {
+ provider = "slicehost";
+ }
protected SlicehostClient client;
protected SshClient.Factory sshFactory;
private Predicate<IPSocket> socketTester;
- protected String provider = "slicehost";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
-
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
diff --git a/providers/softlayer/pom.xml b/providers/softlayer/pom.xml
index 19dc914..d1c2f73 100644
--- a/providers/softlayer/pom.xml
+++ b/providers/softlayer/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.softlayer.endpoint>https://api.softlayer.com/rest</test.softlayer.endpoint>
- <test.softlayer.apiversion>3</test.softlayer.apiversion>
+ <test.softlayer.api-version>3</test.softlayer.api-version>
+ <test.softlayer.build-version></test.softlayer.build-version>
<test.softlayer.identity>FIXME</test.softlayer.identity>
<test.softlayer.credential>FIXME</test.softlayer.credential>
<test.softlayer.image-id />
@@ -107,7 +108,8 @@
<configuration>
<systemPropertyVariables>
<test.softlayer.endpoint>${test.softlayer.endpoint}</test.softlayer.endpoint>
- <test.softlayer.apiversion>${test.softlayer.apiversion}</test.softlayer.apiversion>
+ <test.softlayer.api-version>${test.softlayer.api-version}</test.softlayer.api-version>
+ <test.softlayer.build-version>${test.softlayer.build-version}</test.softlayer.build-version>
<test.softlayer.identity>${test.softlayer.identity}</test.softlayer.identity>
<test.softlayer.credential>${test.softlayer.credential}</test.softlayer.credential>
<test.softlayer.image-id>${test.softlayer.image-id}</test.softlayer.image-id>
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java
index 3befe69..8ad1d7d 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java
@@ -18,13 +18,22 @@
*/
package org.jclouds.softlayer.features;
-import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.softlayer.binders.ProductOrderToJson;
@@ -32,9 +41,7 @@
import org.jclouds.softlayer.domain.ProductOrderReceipt;
import org.jclouds.softlayer.domain.VirtualGuest;
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import java.util.Set;
+import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to VirtualGuest via their REST API.
@@ -121,7 +128,7 @@
@GET
@Path("/SoftLayer_Billing_Item/{id}/cancelService.json")
@Consumes(MediaType.APPLICATION_JSON)
- @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
+ @ExceptionParser(ReturnFalseOnNotFoundOr404.class)
ListenableFuture<Boolean> cancelService(@PathParam("id") long id);
/**
@@ -141,7 +148,7 @@
@GET
@Path("SoftLayer_Virtual_Guest/{id}/getOrderTemplate/MONTHLY.json")
@Consumes(MediaType.APPLICATION_JSON)
- @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<ProductOrder> getOrderTemplate(@PathParam("id") long id);
}
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandler.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandler.java
index 8eb9887..d67d41a 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandler.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandler.java
@@ -61,8 +61,12 @@
}
break;
case 500:
- if (message != null && message.indexOf("Unable to determine package for") != -1) {
- exception = new ResourceNotFoundException(message, exception);
+ if (message != null ){
+ if (message.indexOf("Unable to determine package for") != -1) {
+ exception = new ResourceNotFoundException(message, exception);
+ } else if (message.indexOf("currently an active transaction") != -1) {
+ exception = new IllegalStateException(message, exception);
+ }
}
}
} finally {
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/binders/ProductOrderToJsonTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/binders/ProductOrderToJsonTest.java
index c9cbb88..e847b0b 100644
--- a/providers/softlayer/src/test/java/org/jclouds/softlayer/binders/ProductOrderToJsonTest.java
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/binders/ProductOrderToJsonTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.softlayer.binders;
import com.google.common.collect.ImmutableSet;
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java
index 8d3ddb4..f663f86 100644
--- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerComputeServiceAdapterLiveTest.java
@@ -77,7 +77,7 @@
guest = adapter.createNodeWithGroupEncodedIntoName(group, name, template);
assertEquals(guest.getNode().getHostname(), name);
- assertEquals(guest.getNodeId(), guest.getNode().getId());
+ assertEquals(guest.getNodeId(), guest.getNode().getId() + "");
assertEquals(guest.getNode().getDomain(), template.getOptions().as(SoftLayerTemplateOptions.class)
.getDomainName());
assert InetAddresses.isInetAddress(guest.getNode().getPrimaryBackendIpAddress()) : guest;
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerExperimentLiveTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerExperimentLiveTest.java
index 60cf6ac..8dbb18e 100644
--- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerExperimentLiveTest.java
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/SoftLayerExperimentLiveTest.java
@@ -18,14 +18,13 @@
*/
package org.jclouds.softlayer.compute;
-import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@@ -35,33 +34,21 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", testName = "SoftLayerExperimentLiveTest")
-public class SoftLayerExperimentLiveTest {
- protected String provider = "softlayer";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+@Test(groups = "live", singleThreaded = true, testName = "SoftLayerExperimentLiveTest")
+public class SoftLayerExperimentLiveTest extends BaseVersionedServiceLiveTest {
+ public SoftLayerExperimentLiveTest() {
+ provider = "softlayer";
}
@Test
public void testAndExperiment() {
ComputeServiceContext context = null;
try {
- String identity = checkNotNull(System.getProperty("test.softlayer.identity"), "test.softlayer.identity");
- String credential = checkNotNull(System.getProperty("test.softlayer.credential"), "test.softlayer.credential");
- context = new ComputeServiceContextFactory().createContext("softlayer", identity, credential, ImmutableSet
+ context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
- assertEquals(context.getComputeService().listAssignableLocations().size(), 7);
+ assertEquals(context.getComputeService().listAssignableLocations().size(), 6);
} finally {
if (context != null)
@@ -69,4 +56,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java
index 94e7cd5..aca1585 100644
--- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.softlayer.compute.functions;
import com.google.common.collect.ImmutableSet;
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestClientExpectTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestClientExpectTest.java
new file mode 100644
index 0000000..d4c8124
--- /dev/null
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestClientExpectTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.softlayer.features;
+
+import java.net.URI;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.jclouds.softlayer.SoftLayerClient;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "SoftLayerClientExpectTest")
+public class VirtualGuestClientExpectTest extends BaseRestClientExpectTest<SoftLayerClient> {
+
+
+ public VirtualGuestClientExpectTest() {
+ provider = "softlayer";
+ }
+
+ public void testCancelGuestReturnsTrueOn200AndFalseOn404() {
+
+ HttpRequest cancelGuest11 = HttpRequest.builder().method("GET")
+ .endpoint(URI.create("https://api.softlayer.com/rest/v3/SoftLayer_Billing_Item/11/cancelService.json"))
+ .headers(
+ ImmutableMultimap.<String, String> builder()
+ .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
+ .put("Accept", "application/json").build()).build();
+
+ HttpResponse found = HttpResponse.builder().statusCode(200).build();
+
+ SoftLayerClient clientWhenServiceExists = requestSendsResponse(cancelGuest11, found);
+
+ assert clientWhenServiceExists.getVirtualGuestClient().cancelService(11l);
+
+
+ HttpResponse notFound = HttpResponse.builder().statusCode(404).build();
+
+ SoftLayerClient clientWhenServiceDoesntExist = requestSendsResponse(cancelGuest11, notFound);
+
+ assert !clientWhenServiceDoesntExist.getVirtualGuestClient().cancelService(11l);
+
+ }
+}
\ No newline at end of file
diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerErrorHandlerTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandlerTest.java
similarity index 90%
rename from providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerErrorHandlerTest.java
rename to providers/softlayer/src/test/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandlerTest.java
index c30b7b7..1a083a5 100644
--- a/providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerErrorHandlerTest.java
+++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/handlers/SoftLayerErrorHandlerTest.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.jclouds.softlayer;
+package org.jclouds.softlayer.handlers;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reportMatcher;
@@ -56,6 +56,17 @@
"{\"error\":\"Unable to determine package for 'node2102835255.me.org'.\"}",
ResourceNotFoundException.class);
}
+
+ @Test
+ public void test500MakesIllegalStateExceptionOnActiveTransaction() {
+ assertCodeMakes(
+ "GET",
+ URI.create("https://api.softlayer.com/rest/v3/SoftLayer_Billing_Item/8676376/cancelService.json"),
+ 500,
+ "",
+ "{\"error\":\"There is currently an active transaction.\"}",
+ IllegalStateException.class);
+ }
@Test
public void test401MakesAuthorizationException() {
diff --git a/providers/stratogen-vcloud-mycloud/pom.xml b/providers/stratogen-vcloud-mycloud/pom.xml
index 9f03b32..e354845 100644
--- a/providers/stratogen-vcloud-mycloud/pom.xml
+++ b/providers/stratogen-vcloud-mycloud/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.stratogen-vcloud-mycloud.endpoint>https://vcd.stratogen.net/api</test.stratogen-vcloud-mycloud.endpoint>
- <test.stratogen-vcloud-mycloud.apiversion>1.0</test.stratogen-vcloud-mycloud.apiversion>
+ <test.stratogen-vcloud-mycloud.api-version>1.0</test.stratogen-vcloud-mycloud.api-version>
+ <test.stratogen-vcloud-mycloud.build-version></test.stratogen-vcloud-mycloud.build-version>
<test.stratogen-vcloud-mycloud.identity>FIXME_IDENTITY</test.stratogen-vcloud-mycloud.identity>
<test.stratogen-vcloud-mycloud.credential>FIXME_CREDENTIAL</test.stratogen-vcloud-mycloud.credential>
<test.stratogen-vcloud-mycloud.image-id />
@@ -100,7 +101,8 @@
<configuration>
<systemPropertyVariables>
<test.stratogen-vcloud-mycloud.endpoint>${test.stratogen-vcloud-mycloud.endpoint}</test.stratogen-vcloud-mycloud.endpoint>
- <test.stratogen-vcloud-mycloud.apiversion>${test.stratogen-vcloud-mycloud.apiversion}</test.stratogen-vcloud-mycloud.apiversion>
+ <test.stratogen-vcloud-mycloud.api-version>${test.stratogen-vcloud-mycloud.api-version}</test.stratogen-vcloud-mycloud.api-version>
+ <test.stratogen-vcloud-mycloud.build-version>${test.stratogen-vcloud-mycloud.build-version}</test.stratogen-vcloud-mycloud.build-version>
<test.stratogen-vcloud-mycloud.identity>${test.stratogen-vcloud-mycloud.identity}</test.stratogen-vcloud-mycloud.identity>
<test.stratogen-vcloud-mycloud.credential>${test.stratogen-vcloud-mycloud.credential}</test.stratogen-vcloud-mycloud.credential>
<test.stratogen-vcloud-mycloud.image-id>${test.stratogen-vcloud-mycloud.image-id}</test.stratogen-vcloud-mycloud.image-id>
diff --git a/providers/synaptic-storage/pom.xml b/providers/synaptic-storage/pom.xml
index 82d16c3..8edeaa6 100644
--- a/providers/synaptic-storage/pom.xml
+++ b/providers/synaptic-storage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.synaptic.storage.blobstore.integration.SynapticStorageTestInitializer</test.initializer>
<test.synaptic-storage.endpoint>https://storage.synaptic.att.com</test.synaptic-storage.endpoint>
- <test.synaptic-storage.apiversion>1.3.0</test.synaptic-storage.apiversion>
+ <test.synaptic-storage.api-version>1.3.0</test.synaptic-storage.api-version>
+ <test.synaptic-storage.build-version></test.synaptic-storage.build-version>
<test.synaptic-storage.identity>FIXME_IDENTITY</test.synaptic-storage.identity>
<test.synaptic-storage.credential>FIXME_CREDENTIAL</test.synaptic-storage.credential>
</properties>
@@ -101,7 +102,8 @@
<configuration>
<systemPropertyVariables>
<test.synaptic-storage.endpoint>${test.synaptic-storage.endpoint}</test.synaptic-storage.endpoint>
- <test.synaptic-storage.apiversion>${test.synaptic-storage.apiversion}</test.synaptic-storage.apiversion>
+ <test.synaptic-storage.api-version>${test.synaptic-storage.api-version}</test.synaptic-storage.api-version>
+ <test.synaptic-storage.build-version>${test.synaptic-storage.build-version}</test.synaptic-storage.build-version>
<test.synaptic-storage.identity>${test.synaptic-storage.identity}</test.synaptic-storage.identity>
<test.synaptic-storage.credential>${test.synaptic-storage.credential}</test.synaptic-storage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/providers/trmk-ecloud/pom.xml b/providers/trmk-ecloud/pom.xml
index 4122f6b..517aadb 100644
--- a/providers/trmk-ecloud/pom.xml
+++ b/providers/trmk-ecloud/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.trmk-ecloud.endpoint>https://services.enterprisecloud.terremark.com/api</test.trmk-ecloud.endpoint>
<test.trmk-ecloud.datacenter>MIA</test.trmk-ecloud.datacenter>
- <test.trmk-ecloud.apiversion>0.8b-ext2.8</test.trmk-ecloud.apiversion>
+ <test.trmk-ecloud.api-version>0.8b-ext2.8</test.trmk-ecloud.api-version>
+ <test.trmk-ecloud.build-version></test.trmk-ecloud.build-version>
<test.trmk-ecloud.identity>FIXME</test.trmk-ecloud.identity>
<test.trmk-ecloud.credential>FIXME</test.trmk-ecloud.credential>
<test.trmk-ecloud.image-id />
@@ -102,7 +103,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.trmk-ecloud.endpoint>${test.trmk-ecloud.endpoint}</test.trmk-ecloud.endpoint>
- <test.trmk-ecloud.apiversion>${test.trmk-ecloud.apiversion}</test.trmk-ecloud.apiversion>
+ <test.trmk-ecloud.api-version>${test.trmk-ecloud.api-version}</test.trmk-ecloud.api-version>
+ <test.trmk-ecloud.build-version>${test.trmk-ecloud.build-version}</test.trmk-ecloud.build-version>
<test.trmk-ecloud.identity>${test.trmk-ecloud.identity}</test.trmk-ecloud.identity>
<test.trmk-ecloud.credential>${test.trmk-ecloud.credential}</test.trmk-ecloud.credential>
<test.trmk-ecloud.datacenter>${test.trmk-ecloud.datacenter}</test.trmk-ecloud.datacenter>
diff --git a/providers/trmk-vcloudexpress/pom.xml b/providers/trmk-vcloudexpress/pom.xml
index a306150..13ca895 100644
--- a/providers/trmk-vcloudexpress/pom.xml
+++ b/providers/trmk-vcloudexpress/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.trmk-vcloudexpress.endpoint>https://services.vcloudexpress.terremark.com/api</test.trmk-vcloudexpress.endpoint>
- <test.trmk-vcloudexpress.apiversion>0.8a-ext1.6</test.trmk-vcloudexpress.apiversion>
+ <test.trmk-vcloudexpress.api-version>0.8a-ext1.6</test.trmk-vcloudexpress.api-version>
+ <test.trmk-vcloudexpress.build-version></test.trmk-vcloudexpress.build-version>
<test.trmk-vcloudexpress.identity>FIXME</test.trmk-vcloudexpress.identity>
<test.trmk-vcloudexpress.credential>FIXME</test.trmk-vcloudexpress.credential>
<test.trmk-vcloudexpress.image-id />
@@ -101,7 +102,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.trmk-vcloudexpress.endpoint>${test.trmk-vcloudexpress.endpoint}</test.trmk-vcloudexpress.endpoint>
- <test.trmk-vcloudexpress.apiversion>${test.trmk-vcloudexpress.apiversion}</test.trmk-vcloudexpress.apiversion>
+ <test.trmk-vcloudexpress.api-version>${test.trmk-vcloudexpress.api-version}</test.trmk-vcloudexpress.api-version>
+ <test.trmk-vcloudexpress.build-version>${test.trmk-vcloudexpress.build-version}</test.trmk-vcloudexpress.build-version>
<test.trmk-vcloudexpress.identity>${test.trmk-vcloudexpress.identity}</test.trmk-vcloudexpress.identity>
<test.trmk-vcloudexpress.credential>${test.trmk-vcloudexpress.credential}</test.trmk-vcloudexpress.credential>
<test.trmk-vcloudexpress.image-id>${test.trmk-vcloudexpress.image-id}</test.trmk-vcloudexpress.image-id>
diff --git a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/trmk/vcloudexpress/InternetServiceLiveTest.java b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/trmk/vcloudexpress/InternetServiceLiveTest.java
index e48acf0..46fa7d5 100644
--- a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/trmk/vcloudexpress/InternetServiceLiveTest.java
+++ b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/trmk/vcloudexpress/InternetServiceLiveTest.java
@@ -18,15 +18,13 @@
*/
package org.jclouds.trmk.vcloudexpress;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import java.net.URI;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
-import org.jclouds.Constants;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
@@ -47,8 +45,12 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live", sequential = true)
-public class InternetServiceLiveTest {
+@Test(groups = "live", singleThreaded = true, testName = "InternetServiceLiveTest")
+public class InternetServiceLiveTest extends BaseVersionedServiceLiveTest {
+ public InternetServiceLiveTest() {
+ provider = "trmk-vcloudexpress";
+ }
+
TerremarkVCloudExpressClient tmClient;
private Set<InternetService> services = Sets.newLinkedHashSet();
@@ -89,31 +91,6 @@
delete(services);
}
- protected String provider = "trmk-vcloudexpress";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
- + ".credential");
- endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
- }
-
- protected Properties setupProperties() {
- Properties overrides = new Properties();
- overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
- overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
- overrides.setProperty(provider + ".identity", identity);
- overrides.setProperty(provider + ".credential", credential);
- overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
- return overrides;
- }
@BeforeGroups(groups = { "live" })
public void setupClient() {
diff --git a/resources/NOTICE.txt b/resources/NOTICE.txt
index eef2bb3..03b1527 100644
--- a/resources/NOTICE.txt
+++ b/resources/NOTICE.txt
@@ -18,7 +18,7 @@
====
jclouds
-Copyright 2009-2011 jclouds, Inc.
+Copyright 2009-2012 jclouds, Inc.
This product includes software developed at
jclouds, Inc. (http://www.jclouds.org/).
@@ -32,27 +32,19 @@
This product includes net.oauth.core
distributed under the Apache Software License, Version 2.0.
-net.oauth.signature.pem.PKCS1EncodedPublicKeySpec is taken from net.oauth.core
-distributed under the Apache Software License, Version 2.0.
-(c) 1998-2009 AOL LLC
-
This product includes Gson (http://code.google.com/p/google-gson)
distributed under the Apache Software License, Version 2.0.
-com.google.gson.stream.JsonWriter patches the same class taken from Gson
-distributed under the Apache Software License, Version 2.0.
-(c) 2010 Google Inc.
-
-com.google.gson.ObjectMapTypeAdapter contains pieces of Gson's MapTypeAdapter
-distributed under the Apache Software License, Version 2.0.
-(c) 2010 Google Inc.
-
This product includes Guice (http://code.google.com/p/google-guice)
distributed under the Apache Software License, Version 2.0.
This product includes Guava (http://code.google.com/p/guava-libraries)
distributed under the Apache Software License, Version 2.0.
+org.jclouds.util.Suppliers2 and Suppliers2Test contain pieces of Guava's Suppliers
+distributed under the Apache Software License, Version 2.0.
+(c) 2010 Google Inc.
+
This product includes BouncyCastle (http://www.bouncycastle.org/licence.html)
distributed with the following notice:
"Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
diff --git a/sandbox-apis/elb/pom.xml b/sandbox-apis/elb/pom.xml
index fb57564..f1fdd1c 100644
--- a/sandbox-apis/elb/pom.xml
+++ b/sandbox-apis/elb/pom.xml
@@ -36,12 +36,14 @@
<properties>
<test.elb.zone>us-east-1a</test.elb.zone>
<test.elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.elb.endpoint>
- <test.elb.apiversion>2010-07-01</test.elb.apiversion>
+ <test.elb.api-version>2010-07-01</test.elb.api-version>
+ <test.elb.build-version></test.elb.build-version>
<test.elb.identity>${test.aws.identity}</test.elb.identity>
<test.elb.credential>${test.aws.credential}</test.elb.credential>
<test.elb.compute.provider>ec2</test.elb.compute.provider>
<test.elb.compute.endpoint>https://ec2.us-east-1.amazonaws.com</test.elb.compute.endpoint>
- <test.elb.compute.apiversion>2010-06-15</test.elb.compute.apiversion>
+ <test.elb.compute.api-version>2010-06-15</test.elb.compute.api-version>
+ <test.elb.compute.build-version></test.elb.compute.build-version>
<test.elb.compute.identity>${test.aws.identity}</test.elb.compute.identity>
<test.elb.compute.credential>${test.aws.credential}</test.elb.compute.credential>
<test.elb.compute.image-id></test.elb.compute.image-id>
@@ -113,12 +115,14 @@
<systemPropertyVariables>
<test.elb.zone>${test.elb.zone}</test.elb.zone>
<test.elb.endpoint>${test.elb.endpoint}</test.elb.endpoint>
- <test.elb.apiversion>${test.elb.apiversion}</test.elb.apiversion>
+ <test.elb.api-version>${test.elb.api-version}</test.elb.api-version>
+ <test.elb.build-version>${test.elb.build-version}</test.elb.build-version>
<test.elb.identity>${test.elb.identity}</test.elb.identity>
<test.elb.credential>${test.elb.credential}</test.elb.credential>
<test.elb.compute.provider>${test.elb.compute.provider}</test.elb.compute.provider>
<test.elb.compute.endpoint>${test.elb.compute.endpoint}</test.elb.compute.endpoint>
- <test.elb.compute.apiversion>${test.elb.compute.apiversion}</test.elb.compute.apiversion>
+ <test.elb.compute.api-version>${test.elb.compute.api-version}</test.elb.compute.api-version>
+ <test.elb.compute.build-version>${test.elb.compute.build-version}</test.elb.compute.build-version>
<test.elb.compute.identity>${test.elb.compute.identity}</test.elb.compute.identity>
<test.elb.compute.credential>${test.elb.compute.credential}</test.elb.compute.credential>
<test.elb.compute.image-id>${test.elb.compute.image-id}</test.elb.compute.image-id>
diff --git a/sandbox-apis/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java b/sandbox-apis/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java
index 8f8f285..78c5e8b 100644
--- a/sandbox-apis/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java
+++ b/sandbox-apis/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java
@@ -50,7 +50,7 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected String name = "TestLoadBalancer";
protected void setupCredentials() {
@@ -58,7 +58,7 @@
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -70,8 +70,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-apis/libvirt/pom.xml b/sandbox-apis/libvirt/pom.xml
index 7a07bfa..398cf61 100644
--- a/sandbox-apis/libvirt/pom.xml
+++ b/sandbox-apis/libvirt/pom.xml
@@ -36,7 +36,8 @@
<!-- when instances are hung, open a ticket and add here -->
<jclouds.compute.blacklist.nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist.nodes>
<test.libvirt.endpoint>test:///default</test.libvirt.endpoint>
- <test.libvirt.apiversion>1.0</test.libvirt.apiversion>
+ <test.libvirt.api-version>1.0</test.libvirt.api-version>
+ <test.libvirt.build-version></test.libvirt.build-version>
<test.libvirt.identity>FIXME</test.libvirt.identity>
<test.libvirt.credential>FIXME</test.libvirt.credential>
<test.libvirt.image-id></test.libvirt.image-id>
@@ -126,7 +127,8 @@
<configuration>
<systemPropertyVariables>
<test.libvirt.endpoint>${test.libvirt.endpoint}</test.libvirt.endpoint>
- <test.libvirt.apiversion>${test.libvirt.apiversion}</test.libvirt.apiversion>
+ <test.libvirt.api-version>${test.libvirt.api-version}</test.libvirt.api-version>
+ <test.libvirt.build-version>${test.libvirt.build-version}</test.libvirt.build-version>
<test.libvirt.identity>${test.libvirt.identity}</test.libvirt.identity>
<test.libvirt.credential>${test.libvirt.credential}</test.libvirt.credential>
<test.libvirt.image-id>${test.libvirt.image-id}</test.libvirt.image-id>
diff --git a/sandbox-apis/libvirt/src/test/java/org/jclouds/libvirt/compute/LibvirtExperimentLiveTest.java b/sandbox-apis/libvirt/src/test/java/org/jclouds/libvirt/compute/LibvirtExperimentLiveTest.java
index f49e9c4..3820811 100644
--- a/sandbox-apis/libvirt/src/test/java/org/jclouds/libvirt/compute/LibvirtExperimentLiveTest.java
+++ b/sandbox-apis/libvirt/src/test/java/org/jclouds/libvirt/compute/LibvirtExperimentLiveTest.java
@@ -40,14 +40,14 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
@BeforeClass
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = System.getProperty("test." + provider + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
@Test
@@ -92,4 +92,4 @@
}
}
-}
\ No newline at end of file
+}
diff --git a/sandbox-apis/nirvanix/pom.xml b/sandbox-apis/nirvanix/pom.xml
index 1c07d59..85063ba 100644
--- a/sandbox-apis/nirvanix/pom.xml
+++ b/sandbox-apis/nirvanix/pom.xml
@@ -46,7 +46,8 @@
<properties>
<test.nirvanix.endpoint>http://services.nirvanix.com</test.nirvanix.endpoint>
- <test.nirvanix.apiversion>2.5.6</test.nirvanix.apiversion>
+ <test.nirvanix.api-version>2.5.6</test.nirvanix.api-version>
+ <test.nirvanix.build-version></test.nirvanix.build-version>
<test.nirvanix.identity>FIXME</test.nirvanix.identity>
<test.nirvanix.credential> FIXME </test.nirvanix.credential>
</properties>
@@ -106,7 +107,8 @@
<configuration>
<systemPropertyVariables>
<test.nirvanix.endpoint>${test.nirvanix.endpoint}</test.nirvanix.endpoint>
- <test.nirvanix.apiversion>${test.nirvanix.apiversion}</test.nirvanix.apiversion>
+ <test.nirvanix.api-version>${test.nirvanix.api-version}</test.nirvanix.api-version>
+ <test.nirvanix.build-version>${test.nirvanix.build-version}</test.nirvanix.build-version>
<test.nirvanix.identity>${test.nirvanix.identity}</test.nirvanix.identity>
<test.nirvanix.credential>${test.nirvanix.credential}</test.nirvanix.credential>
</systemPropertyVariables>
diff --git a/sandbox-apis/openstack-nova/pom.xml b/sandbox-apis/openstack-nova/pom.xml
index 7c912a1..9660cb2 100644
--- a/sandbox-apis/openstack-nova/pom.xml
+++ b/sandbox-apis/openstack-nova/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.openstack-nova.endpoint>http://localhost:8774/v1.1/</test.openstack-nova.endpoint>
- <test.openstack-nova.apiversion>v1.1</test.openstack-nova.apiversion>
+ <test.openstack-nova.api-version>v1.1</test.openstack-nova.api-version>
+ <test.openstack-nova.build-version></test.openstack-nova.build-version>
<test.openstack-nova.identity>FIXME_IDENTITY</test.openstack-nova.identity>
<test.openstack-nova.credential>FIXME_CREDENTIALS</test.openstack-nova.credential>
<test.openstack-nova.image-id></test.openstack-nova.image-id>
@@ -115,7 +116,8 @@
<configuration>
<systemPropertyVariables>
<test.openstack-nova.endpoint>${test.openstack-nova.endpoint}</test.openstack-nova.endpoint>
- <test.openstack-nova.apiversion>${test.openstack-nova.apiversion}</test.openstack-nova.apiversion>
+ <test.openstack-nova.api-version>${test.openstack-nova.api-version}</test.openstack-nova.api-version>
+ <test.openstack-nova.build-version>${test.openstack-nova.build-version}</test.openstack-nova.build-version>
<test.openstack-nova.identity>${test.openstack-nova.identity}</test.openstack-nova.identity>
<test.openstack-nova.credential>${test.openstack-nova.credential}</test.openstack-nova.credential>
<test.openstack-nova.image-id>${test.openstack-nova.image-id}</test.openstack-nova.image-id>
diff --git a/sandbox-apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaPropertiesBuilder.java b/sandbox-apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaPropertiesBuilder.java
index 6c744a9..3edac5e 100644
--- a/sandbox-apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaPropertiesBuilder.java
+++ b/sandbox-apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/NovaPropertiesBuilder.java
@@ -37,7 +37,7 @@
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
- properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8774/{apiversion}/{identity}");
+ properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8774/{api-version}/{identity}");
properties.setProperty(PROPERTY_API_VERSION, "v1.1");
return properties;
}
@@ -47,7 +47,7 @@
}
public static final Pattern IDENTITY_PATTERN = Pattern.compile("\\{identity\\}");
- public static final Pattern API_VERSION_PATTERN = Pattern.compile("\\{apiversion\\}");
+ public static final Pattern API_VERSION_PATTERN = Pattern.compile("\\{api-version\\}");
@Override
public Properties build() {
diff --git a/sandbox-apis/pcs/pom.xml b/sandbox-apis/pcs/pom.xml
index 6589e51..dc5ecbd 100644
--- a/sandbox-apis/pcs/pom.xml
+++ b/sandbox-apis/pcs/pom.xml
@@ -46,7 +46,8 @@
<properties>
<test.pcs.endpoint>FIXME</test.pcs.endpoint>
- <test.pcs.apiversion>2</test.pcs.apiversion>
+ <test.pcs.api-version>2</test.pcs.api-version>
+ <test.pcs.build-version></test.pcs.build-version>
<test.pcs.identity>FIXME</test.pcs.identity>
<test.pcs.credential>FIXME</test.pcs.credential>
</properties>
@@ -106,7 +107,8 @@
<configuration>
<systemPropertyVariables>
<test.pcs.endpoint>${test.pcs.endpoint}</test.pcs.endpoint>
- <test.pcs.apiversion>${test.pcs.apiversion}</test.pcs.apiversion>
+ <test.pcs.api-version>${test.pcs.api-version}</test.pcs.api-version>
+ <test.pcs.build-version>${test.pcs.build-version}</test.pcs.build-version>
<test.pcs.identity>${test.pcs.identity}</test.pcs.identity>
<test.pcs.credential>${test.pcs.credential}</test.pcs.credential>
</systemPropertyVariables>
diff --git a/sandbox-apis/pcs/src/test/java/org/jclouds/mezeo/pcs/PCSClientLiveTest.java b/sandbox-apis/pcs/src/test/java/org/jclouds/mezeo/pcs/PCSClientLiveTest.java
index 2621943..337f47b 100644
--- a/sandbox-apis/pcs/src/test/java/org/jclouds/mezeo/pcs/PCSClientLiveTest.java
+++ b/sandbox-apis/pcs/src/test/java/org/jclouds/mezeo/pcs/PCSClientLiveTest.java
@@ -82,14 +82,14 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -100,8 +100,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-apis/scality-rs2/pom.xml b/sandbox-apis/scality-rs2/pom.xml
index 1f8e37d..d11e695 100644
--- a/sandbox-apis/scality-rs2/pom.xml
+++ b/sandbox-apis/scality-rs2/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.scality.rs2.blobstore.ScalityRS2TestInitializer</test.initializer>
<test.scality-rs2.endpoint>FIXME_ENDPOINT</test.scality-rs2.endpoint>
- <test.scality-rs2.apiversion>2006-03-01</test.scality-rs2.apiversion>
+ <test.scality-rs2.api-version>2006-03-01</test.scality-rs2.api-version>
+ <test.scality-rs2.build-version></test.scality-rs2.build-version>
<test.scality-rs2.identity>FIXME_IDENTITY</test.scality-rs2.identity>
<test.scality-rs2.credential>FIXME_CREDENTIAL</test.scality-rs2.credential>
</properties>
@@ -101,7 +102,8 @@
<configuration>
<systemPropertyVariables>
<test.scality-rs2.endpoint>${test.scality-rs2.endpoint}</test.scality-rs2.endpoint>
- <test.scality-rs2.apiversion>${test.scality-rs2.apiversion}</test.scality-rs2.apiversion>
+ <test.scality-rs2.api-version>${test.scality-rs2.api-version}</test.scality-rs2.api-version>
+ <test.scality-rs2.build-version>${test.scality-rs2.build-version}</test.scality-rs2.build-version>
<test.scality-rs2.identity>${test.scality-rs2.identity}</test.scality-rs2.identity>
<test.scality-rs2.credential>${test.scality-rs2.credential}</test.scality-rs2.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/sandbox-apis/simpledb/pom.xml b/sandbox-apis/simpledb/pom.xml
index ac40645..d0ffb06 100644
--- a/sandbox-apis/simpledb/pom.xml
+++ b/sandbox-apis/simpledb/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.simpledb.endpoint>https://sdb.amazonaws.com</test.simpledb.endpoint>
- <test.simpledb.apiversion>2009-04-15</test.simpledb.apiversion>
+ <test.simpledb.api-version>2009-04-15</test.simpledb.api-version>
+ <test.simpledb.build-version></test.simpledb.build-version>
<test.simpledb.identity>${test.aws.identity}</test.simpledb.identity>
<test.simpledb.credential>${test.aws.credential}</test.simpledb.credential>
</properties>
@@ -79,7 +80,8 @@
<configuration>
<systemPropertyVariables>
<test.simpledb.endpoint>${test.simpledb.endpoint}</test.simpledb.endpoint>
- <test.simpledb.apiversion>${test.simpledb.apiversion}</test.simpledb.apiversion>
+ <test.simpledb.api-version>${test.simpledb.api-version}</test.simpledb.api-version>
+ <test.simpledb.build-version>${test.simpledb.build-version}</test.simpledb.build-version>
<test.simpledb.identity>${test.simpledb.identity}</test.simpledb.identity>
<test.simpledb.credential>${test.simpledb.credential}</test.simpledb.credential>
</systemPropertyVariables>
diff --git a/sandbox-apis/simpledb/src/test/java/org/jclouds/simpledb/SimpleDBClientLiveTest.java b/sandbox-apis/simpledb/src/test/java/org/jclouds/simpledb/SimpleDBClientLiveTest.java
index 7783be8..dc60197 100644
--- a/sandbox-apis/simpledb/src/test/java/org/jclouds/simpledb/SimpleDBClientLiveTest.java
+++ b/sandbox-apis/simpledb/src/test/java/org/jclouds/simpledb/SimpleDBClientLiveTest.java
@@ -55,14 +55,14 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -74,8 +74,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-apis/sqs/pom.xml b/sandbox-apis/sqs/pom.xml
index 6c70773..bad642f 100644
--- a/sandbox-apis/sqs/pom.xml
+++ b/sandbox-apis/sqs/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.sqs.endpoint>https://sqs.us-east-1.amazonaws.com</test.sqs.endpoint>
- <test.sqs.apiversion>2009-02-01</test.sqs.apiversion>
+ <test.sqs.api-version>2009-02-01</test.sqs.api-version>
+ <test.sqs.build-version></test.sqs.build-version>
<test.sqs.identity>${test.aws.identity}</test.sqs.identity>
<test.sqs.credential>${test.aws.credential}</test.sqs.credential>
</properties>
@@ -79,7 +80,8 @@
<configuration>
<systemPropertyVariables>
<test.sqs.endpoint>${test.sqs.endpoint}</test.sqs.endpoint>
- <test.sqs.apiversion>${test.sqs.apiversion}</test.sqs.apiversion>
+ <test.sqs.api-version>${test.sqs.api-version}</test.sqs.api-version>
+ <test.sqs.build-version>${test.sqs.build-version}</test.sqs.build-version>
<test.sqs.identity>${test.sqs.identity}</test.sqs.identity>
<test.sqs.credential>${test.sqs.credential}</test.sqs.credential>
</systemPropertyVariables>
diff --git a/sandbox-apis/sqs/src/test/java/org/jclouds/sqs/SQSClientLiveTest.java b/sandbox-apis/sqs/src/test/java/org/jclouds/sqs/SQSClientLiveTest.java
index 2b5139d..2ebff95 100644
--- a/sandbox-apis/sqs/src/test/java/org/jclouds/sqs/SQSClientLiveTest.java
+++ b/sandbox-apis/sqs/src/test/java/org/jclouds/sqs/SQSClientLiveTest.java
@@ -60,14 +60,14 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -79,8 +79,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-apis/virtualbox/README.md b/sandbox-apis/virtualbox/README.md
index 85aa024..73bf6bb 100644
--- a/sandbox-apis/virtualbox/README.md
+++ b/sandbox-apis/virtualbox/README.md
@@ -13,8 +13,8 @@
1. Create a working dir on 'user.home' called by default "jclouds-virtualbox-test"
(this value can be overwritten directly on the commandline using -Dtest.virtualbox.workingDir)
2. Install Virtualbox from the internet (mac os x lion and ubuntu host are supported at the moment)
-3. Download by default an ubuntu 11.04 server i386 ISO into "jclouds-virtualbox-test" from http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso.
-4. Download VirtualBox Guest Additions ISO (tested with VBoxGuestAdditions_4.0.2-update-69551.iso) into "jclouds-virtualbox-test"
+3. Download by default an ubuntu 10.04.3 server i386 ISO into "jclouds-virtualbox-test" from http://releases.ubuntu.com/10.04/ubuntu-10.04.3-server-i386.iso
+4. Download VirtualBox Guest Additions ISO into "jclouds-virtualbox-test" from http://download.virtualbox.org/virtualbox/4.1.8/VBoxGuestAdditions_4.1.8.iso
5. Disable login credential: $ VBoxManage setproperty websrvauthlibrary null
6. Start an embedded jetty server that serves a preseed file specifically written for ubuntu 11.04
7. Start webservice with increasead timeout: $ /usr/bin/vboxwebsrv --timeout 10000 and then will:
@@ -36,4 +36,4 @@
and choose the numberOfVirtualMachine you need using -Dtest.virtualbox.numberOfVirtualMachine=<#ofVMs>,
These VMs will be cloned starting from the golden template VM created before
-It will create a "numberOfVirtualMachine" in a vbox default machine folder with 'VMName_i' name, by cloning the golden template in linked mode with a bridged NIC.
\ No newline at end of file
+It will create a "numberOfVirtualMachine" in a vbox default machine folder with 'VMName_i' name, by cloning the golden template in linked mode with a bridged NIC.
diff --git a/sandbox-apis/virtualbox/pom.xml b/sandbox-apis/virtualbox/pom.xml
index 313d503..f4b3a57 100644
--- a/sandbox-apis/virtualbox/pom.xml
+++ b/sandbox-apis/virtualbox/pom.xml
@@ -35,12 +35,13 @@
<properties>
<test.virtualbox.endpoint>http://localhost:18083/</test.virtualbox.endpoint>
- <test.virtualbox.apiversion>4.1.4</test.virtualbox.apiversion>
+ <test.virtualbox.api-version>4.1.4</test.virtualbox.api-version>
+ <test.virtualbox.build-version>4.1.8r75467</test.virtualbox.build-version>
<test.virtualbox.identity>administrator</test.virtualbox.identity>
<test.virtualbox.credential>12345</test.virtualbox.credential>
- <test.virtualbox.image-id></test.virtualbox.image-id>
- <test.virtualbox.image.login-user></test.virtualbox.image.login-user>
- <test.virtualbox.image.authenticate-sudo></test.virtualbox.image.authenticate-sudo>
+ <test.virtualbox.image-id>ubuntu-11.04-server-i386</test.virtualbox.image-id>
+ <test.virtualbox.image.login-user>toor:password</test.virtualbox.image.login-user>
+ <test.virtualbox.image.authenticate-sudo>true</test.virtualbox.image.authenticate-sudo>
</properties>
<dependencies>
@@ -52,7 +53,7 @@
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>vboxjws</artifactId>
- <version>${test.virtualbox.apiversion}</version>
+ <version>${test.virtualbox.api-version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.api</groupId>
@@ -67,7 +68,6 @@
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
- <version>7.4.0.RC0</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -102,12 +102,6 @@
<version>0.9.29</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.jclouds.driver</groupId>
- <artifactId>jclouds-log4j</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<profiles>
@@ -129,7 +123,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.virtualbox.endpoint>${test.virtualbox.endpoint}</test.virtualbox.endpoint>
- <test.virtualbox.apiversion>${test.virtualbox.apiversion}</test.virtualbox.apiversion>
+ <test.virtualbox.api-version>${test.virtualbox.api-version}</test.virtualbox.api-version>
+ <test.virtualbox.build-version>${test.virtualbox.build-version}</test.virtualbox.build-version>
<test.virtualbox.identity>${test.virtualbox.identity}</test.virtualbox.identity>
<test.virtualbox.credential>${test.virtualbox.credential}</test.virtualbox.credential>
<test.virtualbox.image-id>${test.virtualbox.image-id}</test.virtualbox.image-id>
diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/Preconfiguration.java
similarity index 63%
rename from scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java
rename to sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/Preconfiguration.java
index 43978f0..03bbcbe 100644
--- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/InstallRSAPrivateKey.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/Preconfiguration.java
@@ -16,17 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.jclouds.scriptbuilder.domain;
+package org.jclouds.virtualbox;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
/**
- * @see org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey
+ * Relating to a preseed or KickStart source
+ *
* @author Adrian Cole
+ *
*/
-@Deprecated
-public class InstallRSAPrivateKey extends org.jclouds.scriptbuilder.statements.ssh.InstallRSAPrivateKey {
-
- public InstallRSAPrivateKey(String privateKey) {
- super(privateKey);
- }
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Preconfiguration {
}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java
index 5a1ce56..1b7d6d4 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxContextBuilder.java
@@ -24,8 +24,8 @@
import org.jclouds.compute.StandaloneComputeServiceContextBuilder;
import org.jclouds.virtualbox.config.VirtualBoxComputeServiceContextModule;
-import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Supplier;
import com.google.inject.Module;
/**
@@ -33,10 +33,11 @@
*
* @author Mattias Holmqvist, Andrea Turli
*/
-public class VirtualBoxContextBuilder extends StandaloneComputeServiceContextBuilder<VirtualBoxManager> {
+@SuppressWarnings("unchecked")
+public class VirtualBoxContextBuilder extends StandaloneComputeServiceContextBuilder<Supplier> {
public VirtualBoxContextBuilder(Properties properties) {
- super(VirtualBoxManager.class, properties);
+ super(Supplier.class, properties);
}
@Override
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxPropertiesBuilder.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxPropertiesBuilder.java
index 91877c3..7b2014b 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxPropertiesBuilder.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/VirtualBoxPropertiesBuilder.java
@@ -19,6 +19,8 @@
package org.jclouds.virtualbox;
+import static org.jclouds.Constants.PROPERTY_API_VERSION;
+import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
@@ -27,7 +29,8 @@
import java.util.Properties;
import org.jclouds.PropertiesBuilder;
-import org.jclouds.virtualbox.config.VirtualBoxConstants;
+import static org.jclouds.compute.reference.ComputeServiceConstants.*;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.*;
/**
* Builds properties for VirtualBox integration.
@@ -47,32 +50,34 @@
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
+ properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/");
+ // later version not in maven, yet
+ properties.put(PROPERTY_API_VERSION, "4.1.4");
+ properties.put(PROPERTY_BUILD_VERSION, "4.1.8r75467");
properties.put(PROPERTY_IDENTITY, "administrator");
properties.put(PROPERTY_CREDENTIAL, "12345");
- properties.put(PROPERTY_ENDPOINT, "http://localhost:18083/");
- properties.put(VirtualBoxConstants.VIRTUALBOX_PRESEED_URL, "http://dl.dropbox.com/u/693111/preseed.cfg");
- properties.put(VirtualBoxConstants.VIRTUALBOX_SNAPSHOT_DESCRIPTION, "jclouds-virtualbox-snaphot");
- properties.put(VirtualBoxConstants.VIRTUALBOX_HOSTNAME, "jclouds-virtualbox-kickstart-admin");
- properties
- .put(VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE,
- "<Esc><Esc><Enter> "
- + "/install/vmlinuz noapic preseed/url=http://10.0.2.2:8080/src/test/resources/preseed.cfg "
- + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us "
- + "hostname="
- + properties.get(VirtualBoxConstants.VIRTUALBOX_HOSTNAME)
- + " "
- + "fb=false debconf/frontend=noninteractive "
- + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
- + "initrd=/install/initrd.gz -- <Enter>");
- properties.put(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR, System.getProperty("user.home") + File.separator
- + System.getProperty("test.virtualbox.workingDir", "jclouds-virtualbox-test"));
+ properties.put(PROPERTY_IMAGE_ID, "ubuntu-11.04-server-i386");
+ properties.put(PROPERTY_IMAGE_LOGIN_USER, "toor:password");
+ properties.put(PROPERTY_IMAGE_AUTHENTICATE_SUDO, "true");
- // TODO: Add more properties and use the wired properties from test code.
- properties.put(VirtualBoxConstants.VIRTUALBOX_DISTRO_ISO_NAME, "ubuntu-11.04-server-i386.iso");
+ properties.put(VIRTUALBOX_ISO_URL, "http://releases.ubuntu.com/11.04/ubuntu-11.04-server-i386.iso");
+ properties.put(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, "<Esc><Esc><Enter> "
+ + "/install/vmlinuz noapic preseed/url=PRECONFIGURATION_URL "
+ + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + "HOSTNAME "
+ + "fb=false debconf/frontend=noninteractive "
+ + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
+ + "initrd=/install/initrd.gz -- <Enter>");
+
+ properties.put(VIRTUALBOX_WORKINGDIR, System.getProperty("user.home") + File.separator
+ + System.getProperty("test.virtualbox.workingDir", "jclouds-virtualbox-test"));
- properties.put(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080");
+ properties.put(VIRTUALBOX_PRECONFIGURATION_URL, "http://10.0.2.2:8080/src/test/resources/preseed.cfg");
+
+
+
return properties;
}
+
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java
index 3fb4ac2..0207063 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java
@@ -24,8 +24,6 @@
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
-import java.util.Collections;
-
import javax.inject.Inject;
import org.jclouds.compute.ComputeServiceAdapter;
@@ -43,7 +41,9 @@
import com.google.common.base.Function;
import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
import com.google.inject.Singleton;
/**
@@ -56,12 +56,12 @@
@Singleton
public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter<IMachine, IMachine, Image, Location> {
- private final VirtualBoxManager manager;
+ private final Supplier<VirtualBoxManager> manager;
private final JustProvider justProvider;
- private Function<IMachine, Image> iMachineToImage;
+ private final Function<IMachine, Image> iMachineToImage;
@Inject
- public VirtualBoxComputeServiceAdapter(VirtualBoxManager manager, JustProvider justProvider,
+ public VirtualBoxComputeServiceAdapter(Supplier<VirtualBoxManager> manager, JustProvider justProvider,
Function<IMachine, Image> iMachineToImage) {
this.iMachineToImage = iMachineToImage;
this.manager = checkNotNull(manager, "manager");
@@ -76,24 +76,35 @@
@Override
public Iterable<IMachine> listNodes() {
- return Collections.emptyList();
+ return Iterables.filter(manager.get().getVBox().getMachines(), new Predicate<IMachine>() {
+
+ @Override
+ public boolean apply(IMachine arg0) {
+ return !arg0.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
+ }
+
+ });
}
@Override
public Iterable<IMachine> listHardwareProfiles() {
- return manager.getVBox().getMachines();
+ return imageMachines();
}
@Override
public Iterable<Image> listImages() {
+ return transform(imageMachines(), iMachineToImage);
+ }
+
+ private Iterable<IMachine> imageMachines() {
final Predicate<? super IMachine> imagePredicate = new Predicate<IMachine>() {
@Override
public boolean apply(@Nullable IMachine iMachine) {
return iMachine.getName().startsWith(VIRTUALBOX_IMAGE_PREFIX);
}
};
- final Iterable<IMachine> imageMachines = filter(manager.getVBox().getMachines(), imagePredicate);
- return transform(imageMachines, iMachineToImage);
+ final Iterable<IMachine> imageMachines = filter(manager.get().getVBox().getMachines(), imagePredicate);
+ return imageMachines;
}
@SuppressWarnings("unchecked")
@@ -104,29 +115,29 @@
@Override
public IMachine getNode(String vmName) {
- return manager.getVBox().findMachine(vmName);
+ return manager.get().getVBox().findMachine(vmName);
}
@Override
public void destroyNode(String vmName) {
- IMachine machine = manager.getVBox().findMachine(vmName);
+ IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
machine.unregister(CleanupMode.Full);
}
@Override
public void rebootNode(String vmName) {
- IMachine machine = manager.getVBox().findMachine(vmName);
+ IMachine machine = manager.get().getVBox().findMachine(vmName);
powerDownMachine(machine);
- launchVMProcess(machine, manager.getSessionObject());
+ launchVMProcess(machine, manager.get().getSessionObject());
}
@Override
public void resumeNode(String vmName) {
- IMachine machine = manager.getVBox().findMachine(vmName);
+ IMachine machine = manager.get().getVBox().findMachine(vmName);
ISession machineSession;
try {
- machineSession = manager.openMachineSession(machine);
+ machineSession = manager.get().openMachineSession(machine);
machineSession.getConsole().resume();
machineSession.unlockMachine();
} catch (Exception e) {
@@ -136,10 +147,10 @@
@Override
public void suspendNode(String vmName) {
- IMachine machine = manager.getVBox().findMachine(vmName);
+ IMachine machine = manager.get().getVBox().findMachine(vmName);
ISession machineSession;
try {
- machineSession = manager.openMachineSession(machine);
+ machineSession = manager.get().openMachineSession(machine);
machineSession.getConsole().pause();
machineSession.unlockMachine();
} catch (Exception e) {
@@ -161,7 +172,7 @@
private void powerDownMachine(IMachine machine) {
try {
- ISession machineSession = manager.openMachineSession(machine);
+ ISession machineSession = manager.get().openMachineSession(machine);
IProgress progress = machineSession.getConsole().powerDown();
progress.waitForCompletion(-1);
machineSession.unlockMachine();
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
index 6f3274f..27fbc46 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxComputeServiceContextModule.java
@@ -19,13 +19,16 @@
package org.jclouds.virtualbox.config;
+import java.io.InputStream;
import java.net.URI;
import java.util.Map;
+import java.util.concurrent.ExecutionException;
-import javax.inject.Named;
import javax.inject.Singleton;
-import org.jclouds.Constants;
+import org.jclouds.byon.Node;
+import org.jclouds.byon.functions.NodeToNodeMetadata;
+import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
@@ -34,21 +37,34 @@
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.domain.Location;
import org.jclouds.functions.IdentityFunction;
-import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
+import org.jclouds.predicates.RetryablePredicate;
+import org.jclouds.ssh.SshClient;
+import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.compute.VirtualBoxComputeServiceAdapter;
+import org.jclouds.virtualbox.domain.ExecutionType;
import org.jclouds.virtualbox.functions.IMachineToHardware;
import org.jclouds.virtualbox.functions.IMachineToImage;
import org.jclouds.virtualbox.functions.IMachineToNodeMetadata;
+import org.jclouds.virtualbox.functions.IMachineToSshClient;
+import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
+import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
+import org.jclouds.virtualbox.predicates.SshResponds;
import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Provides;
@@ -57,24 +73,15 @@
/**
* @author Mattias Holmqvist, Andrea Turli
*/
+@SuppressWarnings("unchecked")
public class VirtualBoxComputeServiceContextModule extends
- ComputeServiceAdapterContextModule<VirtualBoxManager, VirtualBoxManager, IMachine, IMachine, Image, Location> {
+ ComputeServiceAdapterContextModule<Supplier, Supplier, IMachine, IMachine, Image, Location> {
public VirtualBoxComputeServiceContextModule() {
- super(VirtualBoxManager.class, VirtualBoxManager.class);
+ super(Supplier.class, Supplier.class);
}
- @Provides
- @Singleton
- protected VirtualBoxManager createInstance(@Provider URI endpoint,
- @Named(Constants.PROPERTY_IDENTITY) String identity, @Named(Constants.PROPERTY_CREDENTIAL) String credential) {
-
- VirtualBoxManager manager = VirtualBoxManager.createInstance("");
- manager.connect(endpoint.toASCIIString(), identity, credential);
- return manager;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings( { "unchecked", "rawtypes" })
@Override
protected void configure() {
super.configure();
@@ -92,6 +99,55 @@
}).to(IMachineToImage.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
+
+ // for byon
+ bind(new TypeLiteral<Function<URI, InputStream>>() {
+ }).to(SupplyFromProviderURIOrNodesProperty.class);
+
+ bind(new TypeLiteral<Function<IMachine, SshClient>>() {
+ }).to(IMachineToSshClient.class);
+
+ bind(ExecutionType.class).toInstance(ExecutionType.GUI);
+ bind(LockType.class).toInstance(LockType.Write);
+
+ }
+
+ @Provides
+ @Singleton
+ @Preconfiguration
+ protected Supplier<URI> preconfiguration(javax.inject.Provider<StartJettyIfNotAlreadyRunning> lazyGet) {
+ return lazyGet.get();
+ }
+
+ @Provides
+ @Singleton
+ protected Function<Supplier<NodeMetadata>, VirtualBoxManager> provideVBox(Supplier<NodeMetadata> host) {
+ return new Function<Supplier<NodeMetadata>, VirtualBoxManager>(){
+
+ @Override
+ public VirtualBoxManager apply(Supplier<NodeMetadata> arg0) {
+ return VirtualBoxManager.createInstance(arg0.get().getId());
+ }
+
+ };
+ }
+
+ @Provides
+ @Singleton
+ protected Supplier defaultClient(Supplier<VirtualBoxManager> in) {
+ return in;
+ }
+
+ @Provides
+ @Singleton
+ protected Supplier<VirtualBoxManager> vbox(javax.inject.Provider<StartVBoxIfNotAlreadyRunning> lazyGet) {
+ return lazyGet.get();
+ }
+
+ @Provides
+ @Singleton
+ protected Predicate<SshClient> sshResponds(SshResponds sshResponds, Timeouts timeouts) {
+ return new RetryablePredicate<SshClient>(sshResponds, timeouts.nodeRunning);
}
@Override
@@ -99,26 +155,37 @@
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("11.04");
}
+ @Provides
+ @Singleton
+ protected Supplier<NodeMetadata> host(Supplier<LoadingCache<String, Node>> nodes, NodeToNodeMetadata converter)
+ throws ExecutionException {
+ return Suppliers.compose(Functions.compose(converter, new Function<LoadingCache<String, Node>, Node>() {
+
+ @Override
+ public Node apply(LoadingCache<String, Node> arg0) {
+ return arg0.apply("host");
+ }
+ }), nodes);
+ }
+
@VisibleForTesting
public static final Map<MachineState, NodeState> machineToNodeState = ImmutableMap
- .<MachineState, NodeState> builder().put(MachineState.Running, NodeState.RUNNING)
- .put(MachineState.PoweredOff, NodeState.SUSPENDED).put(MachineState.DeletingSnapshot, NodeState.PENDING)
- .put(MachineState.DeletingSnapshotOnline, NodeState.PENDING)
- .put(MachineState.DeletingSnapshotPaused, NodeState.PENDING)
- .put(MachineState.FaultTolerantSyncing, NodeState.PENDING)
- .put(MachineState.LiveSnapshotting, NodeState.PENDING)
- .put(MachineState.SettingUp, NodeState.PENDING)
- .put(MachineState.Starting, NodeState.PENDING)
- .put(MachineState.Stopping, NodeState.PENDING)
- .put(MachineState.Restoring, NodeState.PENDING)
- // TODO What to map these states to?
- .put(MachineState.FirstOnline, NodeState.PENDING).put(MachineState.FirstTransient, NodeState.PENDING)
- .put(MachineState.LastOnline, NodeState.PENDING).put(MachineState.LastTransient, NodeState.PENDING)
- .put(MachineState.Teleported, NodeState.PENDING).put(MachineState.TeleportingIn, NodeState.PENDING)
- .put(MachineState.TeleportingPausedVM, NodeState.PENDING)
+ .<MachineState, NodeState> builder().put(MachineState.Running, NodeState.RUNNING).put(
+ MachineState.PoweredOff, NodeState.SUSPENDED)
+ .put(MachineState.DeletingSnapshot, NodeState.PENDING).put(MachineState.DeletingSnapshotOnline,
+ NodeState.PENDING).put(MachineState.DeletingSnapshotPaused, NodeState.PENDING).put(
+ MachineState.FaultTolerantSyncing, NodeState.PENDING).put(MachineState.LiveSnapshotting,
+ NodeState.PENDING).put(MachineState.SettingUp, NodeState.PENDING).put(MachineState.Starting,
+ NodeState.PENDING).put(MachineState.Stopping, NodeState.PENDING).put(MachineState.Restoring,
+ NodeState.PENDING)
+ // TODO What to map these states to?
+ .put(MachineState.FirstOnline, NodeState.PENDING).put(MachineState.FirstTransient, NodeState.PENDING).put(
+ MachineState.LastOnline, NodeState.PENDING).put(MachineState.LastTransient, NodeState.PENDING)
+ .put(MachineState.Teleported, NodeState.PENDING).put(MachineState.TeleportingIn, NodeState.PENDING).put(
+ MachineState.TeleportingPausedVM, NodeState.PENDING)
- .put(MachineState.Aborted, NodeState.ERROR).put(MachineState.Stuck, NodeState.ERROR)
+ .put(MachineState.Aborted, NodeState.ERROR).put(MachineState.Stuck, NodeState.ERROR)
- .put(MachineState.Null, NodeState.UNRECOGNIZED).build();
+ .put(MachineState.Null, NodeState.UNRECOGNIZED).build();
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
index 804718e..5f949ec 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/config/VirtualBoxConstants.java
@@ -27,19 +27,15 @@
*/
public interface VirtualBoxConstants {
- public static final String VIRTUALBOX_IMAGE_PREFIX = "jclouds-image-";
+ public static final String VIRTUALBOX_IMAGE_PREFIX = "jclouds#image#";
- public static final String VIRTUALBOX_PRESEED_URL = "jclouds.virtualbox.preseedurl";
-
- public static final String VIRTUALBOX_SNAPSHOT_DESCRIPTION = "jclouds.virtualbox.snapshotDescription";
+ public static final String VIRTUALBOX_PRECONFIGURATION_URL = "jclouds.virtualbox.preconfigurationurl";
public static final String VIRTUALBOX_INSTALLATION_KEY_SEQUENCE = "jclouds.virtualbox.installationkeysequence";
- public static final String VIRTUALBOX_HOSTNAME = "jclouds.virtualbox.hostname";
-
public static final String VIRTUALBOX_WORKINGDIR = "jclouds.virtualbox.workingdir";
- public static final String VIRTUALBOX_ISOFILE = "jclouds.virtualbox.isofile";
+ public static final String VIRTUALBOX_ISO_URL = "jclouds.virtualbox.isourl";
public static final String VIRTUALBOX_MACHINE_GROUP = "jclouds.virtualbox.machinegroup";
@@ -51,12 +47,6 @@
public static final String VIRTUALBOX_HOST_ID = "jclouds.virtualbox.hostid";
- public static final String VIRTUALBOX_DISTRO_ISO_NAME = "jclouds.virtualbox.distroisoname";
-
- public static final String VIRTUALBOX_JETTY_PORT = "jclouds.virtualbox.jetty.port";
-
- public static final String VIRTUALBOX_JETTY_BASE_RESOURCE = "jclouds.virtualbox.jetty.baseresource";
-
public static final String VIRTUALBOX_WEBSERVER_IDENTITY = "jclouds.virtualbox.webserver.identity";
public static final String VIRTUALBOX_WEBSERVER_CREDENTIAL = "jclouds.virtualbox.webserver.credential";
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/GetIPAddressFromMAC.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/GetIPAddressFromMAC.java
index 9e9ece0..19e5bb7 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/GetIPAddressFromMAC.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/GetIPAddressFromMAC.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.domain;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/InstallGuestAdditions.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/InstallGuestAdditions.java
index fac25bf..68ccedc 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/InstallGuestAdditions.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/InstallGuestAdditions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.virtualbox.domain;
import static com.google.common.base.Preconditions.checkNotNull;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/IsoImage.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/IsoImage.java
index 529535c..a16a379 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/IsoImage.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/IsoImage.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.domain;
import com.google.common.base.Objects;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NatAdapter.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NatAdapter.java
index 18df552..ac2dfae 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NatAdapter.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/NatAdapter.java
@@ -50,11 +50,25 @@
private Set<RedirectRule> redirectRules = Sets.newLinkedHashSet();
+ /**
+ * @param host incoming address
+ * @param hostPort
+ * @param guest guest address or empty string for all addresses
+ * @param guestPort
+ * @return
+ */
public Builder tcpRedirectRule(String host, int hostPort, String guest, int guestPort) {
redirectRules.add(new RedirectRule(NATProtocol.TCP, host, hostPort, guest, guestPort));
return this;
}
-
+
+ /**
+ * @param host incoming address
+ * @param hostPort
+ * @param guest guest address or empty string for all addresses
+ * @param guestPort
+ * @return
+ */
public Builder udpRedirectRule(String host, int hostPort, String guest, int guestPort) {
redirectRules.add(new RedirectRule(NATProtocol.UDP, host, hostPort, guest, guestPort));
return this;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/RedirectRule.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/RedirectRule.java
index e52b3b9..933aa9c 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/RedirectRule.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/RedirectRule.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.domain;
import com.google.common.base.Objects;
@@ -34,7 +33,15 @@
private final int hostPort;
private final String guest;
private final int guestPort;
-
+
+ /**
+ * @param protocol
+ * @param host incoming address
+ * @param hostPort
+ * @param guest guest address or empty string for all addresses
+ * @param guestPort
+ * @return
+ */
public RedirectRule(NATProtocol protocol, String host, int hostPort, String guest, int guestPort) {
checkNotNull(protocol);
checkNotNull(host);
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/StorageController.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/StorageController.java
index 215b091..e163c6c 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/StorageController.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/StorageController.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.domain;
import com.google.common.base.Objects;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/VmSpec.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/VmSpec.java
index acbc32a..8f61cdc 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/VmSpec.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/VmSpec.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.domain;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
index 61a40d8..66c95ef 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/domain/YamlImage.java
@@ -1,5 +1,4 @@
/**
- *
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,11 +15,7 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- *
- * @author Andrea Turli
*/
-
package org.jclouds.virtualbox.domain;
import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrUnrecognized;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AddIDEControllerIfNotExists.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AddIDEControllerIfNotExists.java
index 21a6154..782df20 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AddIDEControllerIfNotExists.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AddIDEControllerIfNotExists.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,14 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.virtualbox.domain.StorageController;
import org.virtualbox_4_1.IMachine;
-import org.virtualbox_4_1.StorageBus;
import org.virtualbox_4_1.VBoxException;
import com.google.common.base.Function;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java
index e7800d2..aa70265 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachine.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.virtualbox_4_1.NetworkAdapterType.Am79C973;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachine.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java
similarity index 69%
rename from sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachine.java
rename to sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java
index 5bd188f..8aced46 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachine.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExists.java
@@ -27,18 +27,19 @@
import org.jclouds.virtualbox.domain.RedirectRule;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.INetworkAdapter;
+import org.virtualbox_4_1.VBoxException;
import com.google.common.base.Function;
/**
* @author Mattias Holmqvist
*/
-public class AttachNATAdapterToMachine implements Function<IMachine, Void> {
+public class AttachNATAdapterToMachineIfNotAlreadyExists implements Function<IMachine, Void> {
private long adapterSlot;
private NatAdapter natAdapter;
- public AttachNATAdapterToMachine(long adapterSlot, NatAdapter natAdapter) {
+ public AttachNATAdapterToMachineIfNotAlreadyExists(long adapterSlot, NatAdapter natAdapter) {
this.adapterSlot = adapterSlot;
this.natAdapter = natAdapter;
}
@@ -48,12 +49,15 @@
INetworkAdapter networkAdapter = machine.getNetworkAdapter(adapterSlot);
networkAdapter.setAttachmentType(NAT);
for (RedirectRule rule : natAdapter.getRedirectRules()) {
- networkAdapter.getNatDriver().addRedirect("guestssh",
- rule.getProtocol(),
- rule.getHost(),
- rule.getHostPort(),
- rule.getGuest(),
- rule.getGuestPort());
+ try {
+ String ruleName = String.format("%s@%s:%s->%s:%s",rule.getProtocol(), rule.getHost(), rule.getHostPort(),
+ rule.getGuest(), rule.getGuestPort());
+ networkAdapter.getNatDriver().addRedirect(ruleName, rule.getProtocol(), rule.getHost(), rule.getHostPort(),
+ rule.getGuest(), rule.getGuestPort());
+ } catch (VBoxException e) {
+ if (e.getMessage().indexOf("already exists") == -1)
+ throw e;
+ }
}
networkAdapter.setEnabled(true);
machine.saveSettings();
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
index dd63a31..adae172 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIMachineIfNotAlreadyExists.java
@@ -19,29 +19,33 @@
package org.jclouds.virtualbox.functions;
-import com.google.common.base.Function;
-import com.google.inject.Inject;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.logging.Logger;
-import org.virtualbox_4_1.*;
+import java.util.ArrayList;
+import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Named;
-import java.util.ArrayList;
-import java.util.List;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApply;
-import static org.virtualbox_4_1.LockType.Write;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.virtualbox.config.VirtualBoxConstants;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.virtualbox_4_1.CloneMode;
+import org.virtualbox_4_1.CloneOptions;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IProgress;
+import org.virtualbox_4_1.ISnapshot;
+import org.virtualbox_4_1.VBoxException;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
/**
- * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the
- * followings: - cloning the master - register the clone machine -
- * ensureBridgedNetworkingIsAppliedToMachine(cloneName, macAddress,
- * hostInterface)
- *
+ * CloneAndRegisterMachineFromIMachineIfNotAlreadyExists will take care of the followings: - cloning
+ * the master - register the clone machine -
+ *
* @author Andrea Turli
*/
public class CloneAndRegisterMachineFromIMachineIfNotAlreadyExists implements Function<IMachine, IMachine> {
@@ -50,46 +54,28 @@
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private VirtualBoxManager manager;
- private ComputeServiceContext context;
- private String settingsFile;
- private String osTypeId;
- private String vmId;
- private boolean forceOverwrite;
- private String cloneName;
- private String hostId;
- private String snapshotName;
- private String snapshotDesc;
- private String controllerIDE;
+ private final Supplier<VirtualBoxManager> manager;
+ private final String workingDir;
+ private final VmSpec vmSpec;
+ private final boolean isLinkedClone;
@Inject
- public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
- VirtualBoxManager manager, ComputeServiceContext context,
- String settingsFile, String osTypeId, String vmId,
- boolean forceOverwrite, String cloneName, String hostId,
- String snapshotName, String snapshotDesc, String controllerIDE) {
+ public CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
+ @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir, VmSpec vmSpec, boolean isLinkedClone) {
this.manager = manager;
- this.context = context;
- this.settingsFile = settingsFile;
- this.osTypeId = osTypeId;
- this.vmId = vmId;
- this.forceOverwrite = forceOverwrite;
- this.cloneName = cloneName;
- this.hostId = hostId;
- this.snapshotName = snapshotName;
- this.snapshotDesc = snapshotDesc;
- this.controllerIDE = controllerIDE;
+ this.workingDir = workingDir;
+ this.vmSpec = vmSpec;
+ this.isLinkedClone = isLinkedClone;
}
@Override
public IMachine apply(@Nullable IMachine master) {
- final IVirtualBox vBox = manager.getVBox();
try {
- vBox.findMachine(cloneName);
- throw new IllegalStateException("Machine " + cloneName + " is already registered.");
+ manager.get().getVBox().findMachine(vmSpec.getVmName());
+ throw new IllegalStateException("Machine " + vmSpec.getVmName() + " is already registered.");
} catch (VBoxException e) {
if (machineNotFoundException(e))
- return cloneMachine(cloneName, master);
+ return cloneMachine(vmSpec, master);
else
throw e;
}
@@ -99,13 +85,17 @@
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ");
}
- private IMachine cloneMachine(String cloneName, IMachine master) {
- IMachine clonedMachine = manager.getVBox().createMachine(settingsFile, cloneName, osTypeId, vmId, forceOverwrite);
+ private IMachine cloneMachine(VmSpec vmSpec, IMachine master) {
+ String settingsFile = manager.get().getVBox().composeMachineFilename(vmSpec.getVmName(), workingDir);
+ IMachine clonedMachine = manager.get().getVBox().createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(),
+ vmSpec.getVmId(), vmSpec.isForceOverwrite());
List<CloneOptions> options = new ArrayList<CloneOptions>();
- options.add(CloneOptions.Link);
+ if (isLinkedClone)
+ options.add(CloneOptions.Link);
- // takeSnapshotIfNotAlreadyExists
- ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, snapshotName, snapshotDesc).apply(master);
+ // TODO snapshot name
+ ISnapshot currentSnapshot = new TakeSnapshotIfNotAlreadyAttached(manager, "snapshotName", "snapshotDesc")
+ .apply(master);
// clone
IProgress progress = currentSnapshot.getMachine().cloneTo(clonedMachine, CloneMode.MachineState, options);
@@ -114,33 +104,8 @@
logger.debug("clone done");
// registering
- manager.getVBox().registerMachine(clonedMachine);
-
- // Bridged Network
- List<String> activeBridgedInterfaces = new RetrieveActiveBridgedInterfaces(context).apply(hostId);
- checkNotNull(activeBridgedInterfaces);
- String macAddress = manager.getVBox().getHost().generateMACAddress();
-
- // TODO this behavior can be improved
- String bridgedInterface = activeBridgedInterfaces.get(0);
- long adapterSlot = 0l;
- ensureBridgedNetworkingIsAppliedToMachine(adapterSlot, cloneName, macAddress, bridgedInterface);
-
- // detach iso
- // TODO: also hard-coded values here
- int controllerPort = 0;
- int device = 0;
- ensureMachineHasDistroMediumDetached(cloneName, controllerIDE, controllerPort, device);
-
+ manager.get().getVBox().registerMachine(clonedMachine);
return clonedMachine;
}
- private void ensureBridgedNetworkingIsAppliedToMachine(long adapterSlot, String vmName, String macAddress, String hostInterface) {
- lockMachineAndApply(manager, Write, vmName, new AttachBridgedAdapterToMachine(adapterSlot, macAddress, hostInterface));
- }
-
- private void ensureMachineHasDistroMediumDetached(String vmName, String controllerIDE, int controllerPort, int device) {
- lockMachineAndApply(manager, Write, vmName, new DetachDistroMediumFromMachine(checkNotNull(controllerIDE, "controllerIDE"), controllerPort, device));
- }
-
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
index 3ce8b33..9d86fd6 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndInstallVm.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,191 +16,135 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.inject.Inject;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.logging.Logger;
-import org.jclouds.net.IPSocket;
-import org.jclouds.ssh.SshException;
-import org.jclouds.virtualbox.domain.*;
-import org.jclouds.virtualbox.settings.KeyboardScancodes;
-import org.virtualbox_4_1.*;
+import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
+import static org.jclouds.virtualbox.util.MachineUtils.applyForMachine;
+import static org.jclouds.virtualbox.util.MachineUtils.lockSessionOnMachineAndApply;
+import static org.virtualbox_4_1.LockType.Shared;
+
+import java.net.URI;
+import java.util.List;
import javax.annotation.Resource;
import javax.inject.Named;
-import java.io.File;
-import java.util.Map;
-import java.util.Set;
+import javax.inject.Singleton;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
-import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
-import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_INSTALLATION_KEY_SEQUENCE;
-import static org.jclouds.virtualbox.util.MachineUtils.*;
-import static org.virtualbox_4_1.LockType.Shared;
-import static org.virtualbox_4_1.LockType.Write;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.config.ValueOfConfigurationKeyOrNull;
+import org.jclouds.logging.Logger;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.ssh.SshClient;
+import org.jclouds.virtualbox.Preconfiguration;
+import org.jclouds.virtualbox.domain.ExecutionType;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.jclouds.virtualbox.settings.KeyboardScancodes;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IProgress;
+import org.virtualbox_4_1.ISession;
+import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+
+@Singleton
public class CreateAndInstallVm implements Function<VmSpec, IMachine> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private final VirtualBoxManager manager;
- private String guestId;
- private final ComputeServiceContext context;
- private final String hostId;
- private final Predicate<IPSocket> socketTester;
- private final String webServerHost;
- private final int webServerPort;
+ private final Supplier<VirtualBoxManager> manager;
+ private final CreateAndRegisterMachineFromIsoIfNotAlreadyExists createAndRegisterMachineFromIsoIfNotAlreadyExists;
+ private final ValueOfConfigurationKeyOrNull valueOfConfigurationKeyOrNull;
+
+ private final Supplier<URI> preconfiguration;
+ private final Predicate<SshClient> sshResponds;
private final ExecutionType executionType;
+ private final Factory scriptRunner;
+ private final Supplier<NodeMetadata> host;
+
+ private final Function<IMachine, SshClient> sshClientForIMachine;
+
@Inject
- public CreateAndInstallVm(VirtualBoxManager manager, String guestId, ComputeServiceContext context,
- String hostId, Predicate<IPSocket> socketTester,
- String webServerHost, int webServerPort, ExecutionType executionType) {
+ public CreateAndInstallVm(
+ Supplier<VirtualBoxManager> manager,
+ CreateAndRegisterMachineFromIsoIfNotAlreadyExists CreateAndRegisterMachineFromIsoIfNotAlreadyExists,
+ ValueOfConfigurationKeyOrNull valueOfConfigurationKeyOrNull,
+ Predicate<SshClient> sshResponds,
+ Function<IMachine, SshClient> sshClientForIMachine,
+ Supplier<NodeMetadata> host, RunScriptOnNode.Factory scriptRunner,
+ @Preconfiguration Supplier<URI> preconfiguration,
+ ExecutionType executionType) {
this.manager = manager;
- this.guestId = guestId;
- this.context = context;
- this.hostId = hostId;
- this.socketTester = socketTester;
- this.webServerHost = webServerHost;
- this.webServerPort = webServerPort;
+ this.createAndRegisterMachineFromIsoIfNotAlreadyExists = CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
+ this.valueOfConfigurationKeyOrNull = valueOfConfigurationKeyOrNull;
+ this.sshResponds = sshResponds;
+ this.sshClientForIMachine = sshClientForIMachine;
+ this.scriptRunner = scriptRunner;
+ this.host = host;
+ this.preconfiguration = preconfiguration;
this.executionType = executionType;
}
@Override
public IMachine apply(VmSpec vmSpec) {
-
- ensureWebServerIsRunning();
-
- final IMachine vm = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(vmSpec);
-
String vmName = vmSpec.getVmName();
- // Change RAM
- ensureMachineHasMemory(vmName, vmSpec.getMemory());
+ // note this may not be reachable, as this likely uses the 10.2.2 address
+ URI preconfigurationUri = preconfiguration.get();
+ String keySequence = valueOfConfigurationKeyOrNull
+ .apply(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE)
+ .replace("PRECONFIGURATION_URL",
+ preconfigurationUri.toASCIIString())
+ .replace("HOSTNAME", vmName);
- Set<StorageController> controllers = vmSpec.getControllers();
- if (controllers.isEmpty()) {
- throw new IllegalStateException(missingIDEControllersMessage(vmSpec));
- }
- StorageController controller = controllers.iterator().next();
- ensureMachineHasIDEControllerNamed(vmName, controller);
- setupHardDisksForController(vmName, controller);
- setupDvdsForController(vmSpec, vmName, controller);
-
- // NAT
- Map<Long, NatAdapter> natNetworkAdapters = vmSpec.getNatNetworkAdapters();
- for (Map.Entry<Long, NatAdapter> natAdapterAndSlot : natNetworkAdapters.entrySet()) {
- long slotId = natAdapterAndSlot.getKey();
- NatAdapter natAdapter = natAdapterAndSlot.getValue();
- ensureNATNetworkingIsAppliedToMachine(vmName, slotId, natAdapter);
- }
+ final IMachine vm = createAndRegisterMachineFromIsoIfNotAlreadyExists
+ .apply(vmSpec);
// Launch machine and wait for it to come online
ensureMachineIsLaunched(vmName);
- final String installKeySequence = System.getProperty(VIRTUALBOX_INSTALLATION_KEY_SEQUENCE, defaultInstallSequence(vmName));
- sendKeyboardSequence(installKeySequence, vmName);
+ sendKeyboardSequence(keySequence, vmName);
- boolean sshDeamonIsRunning = false;
- while (!sshDeamonIsRunning) {
- try {
- if (runScriptOnNode(guestId, "id", wrapInInitScript(false)).getExitCode() == 0) {
- logger.debug("Got response from ssh daemon.");
- sshDeamonIsRunning = true;
- }
- } catch (SshException e) {
- logger.debug("No response from ssh daemon...");
- }
- }
+ SshClient client = sshClientForIMachine.apply(vm);
- logger.debug("Installation of image complete. Powering down...");
- lockSessionOnMachineAndApply(manager, Shared, vmName, new Function<ISession, Void>() {
+ logger.debug(">> awaiting installation to finish node(%s)", vmName);
+ checkState(sshResponds.apply(client),
+ "timed out waiting for guest %s to be accessible via ssh", vmName);
- @Override
- public Void apply(ISession session) {
- IProgress powerDownProgress = session.getConsole().powerDown();
- powerDownProgress.waitForCompletion(-1);
- return null;
- }
+ logger.debug("<< installation of image complete. Powering down node(%s)",
+ vmName);
+ lockSessionOnMachineAndApply(manager.get(), Shared, vmName,
+ new Function<ISession, Void>() {
- });
+ @Override
+ public Void apply(ISession session) {
+ IProgress powerDownProgress = session.getConsole()
+ .powerDown();
+ powerDownProgress.waitForCompletion(-1);
+ return null;
+ }
+
+ });
return vm;
}
- private void setupDvdsForController(VmSpec vmSpecification, String vmName, StorageController controller) {
- Set<IsoImage> dvds = controller.getIsoImages();
- for (IsoImage dvd : dvds) {
- String dvdSource = dvd.getSourcePath();
- final IMedium dvdMedium = manager.getVBox().openMedium(dvdSource, DeviceType.DVD,
- AccessMode.ReadOnly, vmSpecification.isForceOverwrite());
- ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName());
- }
- }
-
- private void setupHardDisksForController(String vmName, StorageController controller) {
- Set<HardDisk> hardDisks = controller.getHardDisks();
- for (HardDisk hardDisk : hardDisks) {
- String sourcePath = hardDisk.getDiskPath();
- if (new File(sourcePath).exists()) {
- boolean deleted = new File(sourcePath).delete();
- if (!deleted) {
- logger.error(String.format("File %s could not be deleted.", sourcePath));
- }
- }
- IMedium medium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
- ensureMachineDevicesAttached(vmName, medium, hardDisk.getDeviceDetails(), controller.getName());
- }
- }
-
- private String missingIDEControllersMessage(VmSpec vmSpecification) {
- return String.format("First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s", vmSpecification);
- }
-
- private void ensureWebServerIsRunning() {
- final IPSocket webServerSocket = new IPSocket(webServerHost, webServerPort);
- if (!socketTester.apply(webServerSocket)) {
- throw new IllegalStateException(String.format("Web server is not running on host %s:%s which is needed to serve preseed.cfg.", webServerHost, webServerPort));
- }
- }
-
private void ensureMachineIsLaunched(String vmName) {
- applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(manager, executionType, ""));
- }
-
- private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails, String controllerName) {
- lockMachineAndApply(manager, Write, vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails, medium, controllerName));
- }
-
- private void ensureMachineHasMemory(String vmName, final long memorySize) {
- lockMachineAndApply(manager, Write, vmName, new ApplyMemoryToMachine(memorySize));
- }
-
- private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId, NatAdapter natAdapter) {
- lockMachineAndApply(manager, Write, vmName, new AttachNATAdapterToMachine(slotId, natAdapter));
- }
-
- public void ensureMachineHasIDEControllerNamed(String vmName, StorageController storageController) {
- lockMachineAndApply(manager, Write, checkNotNull(vmName, "vmName"),
- new AddIDEControllerIfNotExists(checkNotNull(storageController, "storageController")));
- }
-
- private String defaultInstallSequence(String vmName) {
- return "<Esc><Esc><Enter> "
- + "/install/vmlinuz noapic preseed/url=http://10.0.2.2:" + webServerPort + "/src/test/resources/preseed.cfg "
- + "debian-installer=en_US auto locale=en_US kbd-chooser/method=us " + "hostname=" + vmName + " "
- + "fb=false debconf/frontend=noninteractive "
- + "keyboard-configuration/layout=USA keyboard-configuration/variant=USA console-setup/ask_detect=false "
- + "initrd=/install/initrd.gz -- <Enter>";
+ applyForMachine(manager.get(), vmName,
+ new LaunchMachineIfNotAlreadyRunning(manager.get(), executionType,
+ ""));
}
private void sendKeyboardSequence(String keyboardSequence, String vmName) {
@@ -209,16 +153,20 @@
for (String line : splitSequence) {
String converted = stringToKeycode(line);
for (String word : converted.split(" ")) {
- sb.append("vboxmanage controlvm ").append(vmName).append(" keyboardputscancode ").append(word).append("; ");
+ sb.append("vboxmanage controlvm ").append(vmName)
+ .append(" keyboardputscancode ").append(word).append("; ");
runScriptIfWordEndsWith(sb, word, "<Enter>");
runScriptIfWordEndsWith(sb, word, "<Return>");
}
}
}
- private void runScriptIfWordEndsWith(StringBuilder sb, String word, String key) {
+ private void runScriptIfWordEndsWith(StringBuilder sb, String word,
+ String key) {
if (word.endsWith(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get(key))) {
- runScriptOnNode(hostId, sb.toString(), runAsRoot(false).wrapInInitScript(false));
+ scriptRunner
+ .create(host.get(), Statements.exec(sb.toString()),
+ runAsRoot(false).wrapInInitScript(false)).init().call();
sb.delete(0, sb.length() - 1);
}
}
@@ -228,7 +176,9 @@
if (s.startsWith("<")) {
String[] specials = s.split("<");
for (int i = 1; i < specials.length; i++) {
- keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<" + specials[i])).append(" ");
+ keycodes.append(
+ KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<"
+ + specials[i])).append(" ");
}
return keycodes.toString();
}
@@ -242,13 +192,11 @@
keycodes.append(" ");
i++;
}
- keycodes.append(KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Spacebar>")).append(" ");
+ keycodes.append(
+ KeyboardScancodes.SPECIAL_KEYBOARD_BUTTON_MAP.get("<Spacebar>"))
+ .append(" ");
return keycodes.toString();
}
- protected ExecResponse runScriptOnNode(String nodeId, String command, RunScriptOptions options) {
- return context.getComputeService().runScriptOnNode(nodeId, command, options);
- }
-
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java
index c30d392..5947b6e 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExists.java
@@ -19,29 +19,63 @@
package org.jclouds.virtualbox.functions;
-import com.google.common.base.Function;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApply;
+import static org.virtualbox_4_1.LockType.Write;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.virtualbox.config.VirtualBoxConstants;
+import org.jclouds.virtualbox.domain.DeviceDetails;
+import org.jclouds.virtualbox.domain.HardDisk;
+import org.jclouds.virtualbox.domain.IsoImage;
+import org.jclouds.virtualbox.domain.NatAdapter;
+import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
+import org.virtualbox_4_1.AccessMode;
+import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
-import javax.annotation.Nullable;
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
/**
* @author Mattias Holmqvist
*/
+@Singleton
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExists implements Function<VmSpec, IMachine> {
- private VirtualBoxManager manager;
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
- public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(VirtualBoxManager manager) {
+ private final Supplier<VirtualBoxManager> manager;
+ private final String workingDir;
+
+ @Inject
+ public CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Supplier<VirtualBoxManager> manager,
+ @Named(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR) String workingDir) {
this.manager = manager;
+ this.workingDir = workingDir;
}
@Override
public IMachine apply(@Nullable VmSpec launchSpecification) {
- final IVirtualBox vBox = manager.getVBox();
+ final IVirtualBox vBox = manager.get().getVBox();
String vmName = launchSpecification.getVmName();
try {
vBox.findMachine(vmName);
@@ -58,12 +92,89 @@
return e.getMessage().contains("VirtualBox error: Could not find a registered machine named ");
}
- private IMachine createMachine(IVirtualBox vBox, VmSpec launchSpecification) {
- // TODO: add support for settingsfile
- String settingsFile1 = null;
- IMachine newMachine = vBox.createMachine(settingsFile1, launchSpecification.getVmName(),
- launchSpecification.getOsTypeId(), launchSpecification.getVmId(), launchSpecification.isForceOverwrite());
- manager.getVBox().registerMachine(newMachine);
+ private IMachine createMachine(IVirtualBox vBox, VmSpec vmSpec) {
+ String settingsFile = vBox.composeMachineFilename(vmSpec.getVmName(), workingDir);
+
+ IMachine newMachine = vBox.createMachine(settingsFile, vmSpec.getVmName(), vmSpec.getOsTypeId(),
+ vmSpec.getVmId(), vmSpec.isForceOverwrite());
+ manager.get().getVBox().registerMachine(newMachine);
+ ensureConfiguration(vmSpec);
return newMachine;
}
+
+ private void ensureConfiguration(VmSpec vmSpec) {
+ String vmName = vmSpec.getVmName();
+
+ // Change RAM
+ ensureMachineHasMemory(vmName, vmSpec.getMemory());
+
+ Set<StorageController> controllers = vmSpec.getControllers();
+ if (controllers.isEmpty()) {
+ throw new IllegalStateException(missingIDEControllersMessage(vmSpec));
+ }
+ StorageController controller = controllers.iterator().next();
+ ensureMachineHasStorageControllerNamed(vmName, controller);
+ setupHardDisksForController(vmName, controller);
+ setupDvdsForController(vmSpec, vmName, controller);
+
+ // NAT
+ Map<Long, NatAdapter> natNetworkAdapters = vmSpec.getNatNetworkAdapters();
+ for (Map.Entry<Long, NatAdapter> natAdapterAndSlot : natNetworkAdapters.entrySet()) {
+ long slotId = natAdapterAndSlot.getKey();
+ NatAdapter natAdapter = natAdapterAndSlot.getValue();
+ ensureNATNetworkingIsAppliedToMachine(vmName, slotId, natAdapter);
+ }
+ }
+
+ private void setupDvdsForController(VmSpec vmSpecification, String vmName, StorageController controller) {
+ Set<IsoImage> dvds = controller.getIsoImages();
+ for (IsoImage dvd : dvds) {
+ String dvdSource = dvd.getSourcePath();
+ final IMedium dvdMedium = manager.get().getVBox().openMedium(dvdSource, DeviceType.DVD, AccessMode.ReadOnly,
+ vmSpecification.isForceOverwrite());
+ ensureMachineDevicesAttached(vmName, dvdMedium, dvd.getDeviceDetails(), controller.getName());
+ }
+ }
+
+ private void ensureMachineDevicesAttached(String vmName, IMedium medium, DeviceDetails deviceDetails,
+ String controllerName) {
+ lockMachineAndApply(manager.get(), Write, vmName, new AttachMediumToMachineIfNotAlreadyAttached(deviceDetails, medium,
+ controllerName));
+ }
+
+ private String missingIDEControllersMessage(VmSpec vmSpecification) {
+ return String
+ .format(
+ "First controller is not an IDE controller. Please verify that the VM spec is a correct master node: %s",
+ vmSpecification);
+ }
+
+ private void setupHardDisksForController(String vmName, StorageController controller) {
+ Set<HardDisk> hardDisks = controller.getHardDisks();
+ for (HardDisk hardDisk : hardDisks) {
+ String sourcePath = hardDisk.getDiskPath();
+ if (new File(sourcePath).exists()) {
+ boolean deleted = new File(sourcePath).delete();
+ if (!deleted) {
+ logger.error(String.format("File %s could not be deleted.", sourcePath));
+ }
+ }
+ IMedium medium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ ensureMachineDevicesAttached(vmName, medium, hardDisk.getDeviceDetails(), controller.getName());
+ }
+ }
+
+ private void ensureMachineHasMemory(String vmName, final long memorySize) {
+ lockMachineAndApply(manager.get(), Write, vmName, new ApplyMemoryToMachine(memorySize));
+ }
+
+ private void ensureNATNetworkingIsAppliedToMachine(String vmName, long slotId,
+ NatAdapter natAdapter) {
+ lockMachineAndApply(manager.get(), Write, vmName, new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter));
+ }
+
+ public void ensureMachineHasStorageControllerNamed(String vmName, StorageController storageController) {
+ lockMachineAndApply(manager.get(), Write, checkNotNull(vmName, "vmName"), new AddIDEControllerIfNotExists(checkNotNull(
+ storageController, "storageController")));
+ }
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExists.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExists.java
index c8a45ca..d0b3f7c 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExists.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExists.java
@@ -19,34 +19,60 @@
package org.jclouds.virtualbox.functions;
-import com.google.common.base.Function;
-import org.jclouds.virtualbox.domain.HardDisk;
-import org.virtualbox_4_1.*;
+import static org.jclouds.virtualbox.util.MachineUtils.lockMachineAndApply;
+import static org.virtualbox_4_1.LockType.Write;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.annotation.Nullable;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.virtualbox.domain.HardDisk;
+import org.virtualbox_4_1.DeviceType;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IMediumAttachment;
+import org.virtualbox_4_1.IProgress;
+import org.virtualbox_4_1.IVirtualBox;
+import org.virtualbox_4_1.VBoxException;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+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 Mattias Holmqvist
*/
+@Singleton
public class CreateMediumIfNotAlreadyExists implements Function<HardDisk, IMedium> {
- private final VirtualBoxManager manager;
- private boolean overwriteIfExists;
+ private final Supplier<VirtualBoxManager> manager;
+ private final boolean overwriteIfExists;
- public CreateMediumIfNotAlreadyExists(VirtualBoxManager manager, boolean overwriteIfExists) {
+ @Inject
+ public CreateMediumIfNotAlreadyExists(Supplier<VirtualBoxManager> manager, boolean overwriteIfExists) {
this.manager = manager;
this.overwriteIfExists = overwriteIfExists;
}
+ public static final Pattern ATTACHED_PATTERN = Pattern.compile(".*is still attached.*: ([-0-9a-f]+) .*");
+
@Override
public IMedium apply(@Nullable HardDisk hardDisk) {
- IVirtualBox vBox = manager.getVBox();
+ IVirtualBox vBox = manager.get().getVBox();
try {
String diskPath = hardDisk.getDiskPath();
final IMedium medium = vBox.findMedium(diskPath, DeviceType.HardDisk);
if (overwriteIfExists) {
- final IProgress progress = medium.deleteStorage();
- progress.waitForCompletion(-1);
+ try {
+ deleteMediumAndBlockUntilComplete(medium);
+ } catch (VBoxException e) {
+ onAlreadyAttachedExceptionDetachOrPropagate(vBox, medium, e);
+ }
return createNewMedium(vBox, hardDisk);
} else {
throw new IllegalStateException("Medium for path " + diskPath + " already exists.");
@@ -58,6 +84,30 @@
}
}
+ private void onAlreadyAttachedExceptionDetachOrPropagate(IVirtualBox vBox, final IMedium medium, VBoxException e) {
+ Matcher matcher = ATTACHED_PATTERN.matcher(e.getMessage());
+ if (matcher.find()) {
+ String machineId = matcher.group(1);
+ IMachine immutableMachine = vBox.findMachine(machineId);
+ IMediumAttachment mediumAttachment = Iterables.find(immutableMachine.getMediumAttachments(),
+ new Predicate<IMediumAttachment>() {
+ public boolean apply(IMediumAttachment in) {
+ return in.getMedium().getId().equals(medium.getId());
+ }
+ });
+ lockMachineAndApply(manager.get(), Write, immutableMachine.getName(), new DetachDistroMediumFromMachine(
+ mediumAttachment.getController(), mediumAttachment.getPort(), mediumAttachment.getDevice()));
+ deleteMediumAndBlockUntilComplete(medium);
+ } else {
+ throw e;
+ }
+ }
+
+ void deleteMediumAndBlockUntilComplete(IMedium medium) {
+ final IProgress progress = medium.deleteStorage();
+ progress.waitForCompletion(-1);
+ }
+
private IMedium createNewMedium(IVirtualBox vBox, HardDisk hardDisk) {
IMedium medium = vBox.createHardDisk(hardDisk.getDiskFormat(), hardDisk.getDiskPath());
createBaseStorage(medium);
@@ -72,7 +122,7 @@
try {
long size = 4L * 1024L * 1024L * 1024L - 4L;
IProgress storageCreation = hardDisk.createBaseStorage(size,
- (long) org.virtualbox_4_1.jaxws.MediumVariant.STANDARD.ordinal());
+ (long) org.virtualbox_4_1.jaxws.MediumVariant.STANDARD.ordinal());
storageCreation.waitForCompletion(-1);
} catch (VBoxException e) {
if (fileNotFoundException(e)) {
@@ -94,7 +144,7 @@
private boolean storageAlreadyExists(VBoxException e) {
return e.getMessage().contains("VirtualBox error: Storage for the medium ")
- && e.getMessage().contains("is already created");
+ && e.getMessage().contains("is already created");
}
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/DetachDistroMediumFromMachine.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/DetachDistroMediumFromMachine.java
index 827dff0..7f744e1 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/DetachDistroMediumFromMachine.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/DetachDistroMediumFromMachine.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import javax.annotation.Nullable;
@@ -32,19 +31,20 @@
public class DetachDistroMediumFromMachine implements Function<IMachine, Void> {
private final String controller;
- private int controllerPort;
- private int device;
+ private int port;
+ private int deviceSlot;
- public DetachDistroMediumFromMachine(String controller, int controllerPort, int device) {
+ public DetachDistroMediumFromMachine(String controller, int port, int deviceSlot) {
this.controller = controller;
- this.controllerPort = controllerPort;
- this.device = device;
+ this.port = port;
+ this.deviceSlot = deviceSlot;
}
+ //TODO: should this be a function on HardDisk?
@Override
public Void apply(@Nullable IMachine machine) {
try {
- machine.detachDevice(controller, controllerPort, device);
+ machine.detachDevice(controller, port, deviceSlot);
machine.saveSettings();
} catch (VBoxException e) {
if (!alreadyDetached(e))
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToHardware.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToHardware.java
index 3bebaa7..3c4ff2d 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToHardware.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToHardware.java
@@ -30,13 +30,14 @@
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
+import com.google.common.base.Supplier;
public class IMachineToHardware implements Function<IMachine, Hardware> {
- private VirtualBoxManager virtualBoxManager;
+ private Supplier<VirtualBoxManager> virtualBoxManager;
@Inject
- public IMachineToHardware(VirtualBoxManager virtualBoxManager) {
+ public IMachineToHardware(Supplier<VirtualBoxManager> virtualBoxManager) {
this.virtualBoxManager = virtualBoxManager;
}
@@ -44,7 +45,7 @@
public Hardware apply(@Nullable IMachine vm) {
String osTypeId = vm.getOSTypeId();
- IGuestOSType guestOSType = virtualBoxManager.getVBox().getGuestOSType(osTypeId);
+ IGuestOSType guestOSType = virtualBoxManager.get().getVBox().getGuestOSType(osTypeId);
Boolean is64Bit = guestOSType.getIs64Bit();
HardwareBuilder hardwareBuilder = new HardwareBuilder();
hardwareBuilder.ids(vm.getId());
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToImage.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToImage.java
index b3b4f26..acc8ccd 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToImage.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToImage.java
@@ -38,15 +38,16 @@
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
+import com.google.common.base.Supplier;
@Singleton
public class IMachineToImage implements Function<IMachine, Image> {
- private final VirtualBoxManager virtualboxManager;
+ private final Supplier<VirtualBoxManager> virtualboxManager;
private final Map<OsFamily, Map<String, String>> osVersionMap;
@Inject
- public IMachineToImage(VirtualBoxManager virtualboxManager, Map<OsFamily, Map<String, String>> osVersionMap) {
+ public IMachineToImage(Supplier<VirtualBoxManager> virtualboxManager, Map<OsFamily, Map<String, String>> osVersionMap) {
this.virtualboxManager = checkNotNull(virtualboxManager, "virtualboxManager");
this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap");
}
@@ -56,7 +57,7 @@
if (from == null)
return null;
- IGuestOSType guestOSType = virtualboxManager.getVBox().getGuestOSType(from.getOSTypeId());
+ IGuestOSType guestOSType = virtualboxManager.get().getVBox().getGuestOSType(from.getOSTypeId());
OsFamily family = parseOsFamilyOrUnrecognized(guestOSType.getDescription());
String version = parseVersionOrReturnEmptyString(family, guestOSType.getDescription(), osVersionMap);
OperatingSystem os = OperatingSystem.builder().description(guestOSType.getDescription()).family(family)
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
index ee7d74e..1976e64 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadata.java
@@ -33,7 +33,6 @@
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.domain.Credentials;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.javax.annotation.Nullable;
@@ -43,6 +42,9 @@
import org.virtualbox_4_1.MachineState;
import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
public class IMachineToNodeMetadata implements Function<IMachine, NodeMetadata> {
@@ -54,8 +56,7 @@
public NodeMetadata apply(@Nullable IMachine vm) {
NodeMetadataBuilder nodeMetadataBuilder = new NodeMetadataBuilder();
- String s = vm.getName();
- nodeMetadataBuilder.name(s);
+ nodeMetadataBuilder.name(vm.getName()).ids(vm.getName());
// TODO Set up location properly
LocationBuilder locationBuilder = new LocationBuilder();
@@ -79,7 +80,7 @@
hardwareBuilder.is64Bit(false);
nodeMetadataBuilder.hostname(vm.getName());
- nodeMetadataBuilder.loginPort(18083);
+
MachineState vmState = vm.getState();
NodeState nodeState = machineToNodeState.get(vmState);
@@ -91,14 +92,21 @@
INetworkAdapter networkAdapter = vm.getNetworkAdapter(0l);
if (networkAdapter != null) {
- String bridgedInterface = networkAdapter.getBridgedInterface();
- System.out.println("Interface: " + bridgedInterface);
+ nodeMetadataBuilder.privateAddresses(ImmutableSet.of(networkAdapter.getNatDriver().getHostIP()));
+ for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()){
+ Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
+ String protocolNumber = Iterables.get(stuff, 1);
+ String hostAddress= Iterables.get(stuff, 2);
+ String inboundPort= Iterables.get(stuff, 3);
+ String targetPort= Iterables.get(stuff, 5);
+ if ("1".equals(protocolNumber) && "22".equals(targetPort))
+ nodeMetadataBuilder.privateAddresses(ImmutableSet.of(hostAddress)).loginPort(Integer.parseInt(inboundPort));
+ }
}
// nodeMetadataBuilder.imageId("");
// nodeMetadataBuilder.group("");
- nodeMetadataBuilder.id(vm.getId());
return nodeMetadataBuilder.build();
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java
new file mode 100644
index 0000000..97020ab
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToSshClient.java
@@ -0,0 +1,66 @@
+/**
+ * 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.virtualbox.functions;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import javax.inject.Singleton;
+
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.net.IPSocket;
+import org.jclouds.ssh.SshClient;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.INetworkAdapter;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+
+@Singleton
+public class IMachineToSshClient implements Function<IMachine, SshClient> {
+ private final SshClient.Factory sshClientFactory;
+
+ @Inject
+ public IMachineToSshClient(SshClient.Factory sshClientFactory) {
+ this.sshClientFactory = sshClientFactory;
+ }
+
+ @Override
+ public SshClient apply(final IMachine vm) {
+ INetworkAdapter networkAdapter = vm.getNetworkAdapter(0l);
+ SshClient client = null;
+ checkState(networkAdapter != null);
+ for (String nameProtocolnumberAddressInboudportGuestTargetport : networkAdapter.getNatDriver().getRedirects()) {
+ Iterable<String> stuff = Splitter.on(',').split(nameProtocolnumberAddressInboudportGuestTargetport);
+ String protocolNumber = Iterables.get(stuff, 1);
+ String hostAddress = Iterables.get(stuff, 2);
+ String inboundPort = Iterables.get(stuff, 3);
+ String targetPort = Iterables.get(stuff, 5);
+ // TODO: we need a way to align the default login credentials from the iso with the
+ // vmspec
+ if ("1".equals(protocolNumber) && "22".equals(targetPort)) {
+ client = sshClientFactory.create(new IPSocket(hostAddress, Integer.parseInt(inboundPort)),
+ LoginCredentials.builder().user("toor").password("password").authenticateSudo(true).build());
+ }
+
+ }
+ return client;
+ }
+}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToVmSpec.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToVmSpec.java
new file mode 100644
index 0000000..60ea631
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/IMachineToVmSpec.java
@@ -0,0 +1,104 @@
+/**
+ * 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.virtualbox.functions;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.virtualbox.domain.HardDisk;
+import org.jclouds.virtualbox.domain.StorageController;
+import org.jclouds.virtualbox.domain.StorageController.Builder;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.virtualbox_4_1.CleanupMode;
+import org.virtualbox_4_1.DeviceType;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IMediumAttachment;
+import org.virtualbox_4_1.IStorageController;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+
+/**
+ * Get a VmSpec from an IMachine
+ *
+ * @author Andrea Turli
+ */
+public class IMachineToVmSpec implements Function<IMachine, VmSpec> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ @Override
+ public VmSpec apply(@Nullable IMachine machine) {
+ List<StorageController> controllers = buildControllers(machine);
+
+ // TODO some parameters are predefined cause the IMachine doesn't have the
+ // concept i.e.: cleanUpMode
+ org.jclouds.virtualbox.domain.VmSpec.Builder vmSpecBuilder = VmSpec
+ .builder();
+
+ vmSpecBuilder.id(machine.getId()).name(machine.getName())
+ .memoryMB(machine.getMemorySize().intValue())
+ .osTypeId(machine.getOSTypeId()).forceOverwrite(true)
+ .cleanUpMode(CleanupMode.Full);
+
+ for (StorageController storageController : controllers) {
+ vmSpecBuilder.controller(storageController);
+ }
+
+ return vmSpecBuilder.build();
+ }
+
+ private List<StorageController> buildControllers(IMachine machine) {
+
+ List<StorageController> controllers = Lists.newArrayList();
+ for (IStorageController iStorageController : machine
+ .getStorageControllers()) {
+
+ Builder storageControlleBuiler = StorageController.builder();
+ for (IMediumAttachment iMediumAttachment : machine
+ .getMediumAttachmentsOfController(iStorageController.getName())) {
+ IMedium iMedium = iMediumAttachment.getMedium();
+ if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
+ storageControlleBuiler.attachHardDisk(HardDisk.builder()
+ .diskpath(iMedium.getLocation()).autoDelete(true)
+ .controllerPort(iMediumAttachment.getPort())
+ .deviceSlot(iMediumAttachment.getDevice().intValue())
+ .build());
+ } else if (iMedium.getDeviceType().equals(DeviceType.DVD)) {
+ storageControlleBuiler.attachISO(iMediumAttachment.getPort(),
+ iMediumAttachment.getDevice().intValue(),
+ iMedium.getLocation());
+ }
+ }
+ controllers.add(storageControlleBuiler
+ .name(iStorageController.getName())
+ .bus(iStorageController.getBus()).build());
+ }
+ return controllers;
+ }
+}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java
index 71ff12b..e07e5fb 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunning.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static com.google.common.base.Throwables.propagate;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MutableMachine.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MutableMachine.java
new file mode 100644
index 0000000..409bdeb
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/MutableMachine.java
@@ -0,0 +1,85 @@
+/*
+ * 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.virtualbox.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.ISession;
+import org.virtualbox_4_1.LockType;
+import org.virtualbox_4_1.VBoxException;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+
+@Singleton
+public class MutableMachine implements Function<String, IMachine> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier<VirtualBoxManager> manager;
+ private final LockType lockType;
+
+
+ @Inject
+ public MutableMachine(Supplier<VirtualBoxManager> manager,
+ LockType lockType) {
+ this.manager = manager;
+ this.lockType = lockType;
+ }
+
+ @Override
+ public IMachine apply(String machineId) {
+ return lockSessionOnMachineAndReturn(manager.get(), lockType, machineId);
+ }
+
+ /**
+ * Locks the machine and executes the given function using the current session.
+ * Since the machine is locked it is possible to perform some modifications to the IMachine.
+ * <p/>
+ * Unlocks the machine before returning.
+ *
+ * @param manager the VirtualBoxManager
+ * @param type the kind of lock to use when initially locking the machine.
+ * @param machineId the id of the machine
+ * @return the result from applying the function to the session.
+ */
+ public static IMachine lockSessionOnMachineAndReturn(VirtualBoxManager manager, LockType type, String machineId) {
+ try {
+ ISession session = manager.getSessionObject();
+ IMachine immutableMachine = manager.getVBox().findMachine(machineId);
+ immutableMachine.lockMachine(session, type);
+ return immutableMachine;
+ } catch (VBoxException e) {
+ throw new RuntimeException(String.format("error locking %s with %s lock: %s", machineId,
+ type, e.getMessage()), e);
+ }
+ }
+
+
+}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java
index 5e1e4a2..caa6d97 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfaces.java
@@ -31,9 +31,12 @@
import javax.annotation.Resource;
-import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.Statements;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
@@ -47,27 +50,25 @@
/**
* @author Andrea Turli
*/
-public class RetrieveActiveBridgedInterfaces implements Function<String, List<String>> {
+public class RetrieveActiveBridgedInterfaces implements Function<NodeMetadata, List<String>> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private ComputeServiceContext context;
+ private final Factory runScriptOnNodeFactory;
@Inject
- public RetrieveActiveBridgedInterfaces(ComputeServiceContext context) {
- this.context = context;
+ public RetrieveActiveBridgedInterfaces(Factory runScriptOnNodeFactory) {
+ this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
}
@Override
- public List<String> apply(String hostId) {
+ public List<String> apply(NodeMetadata host) {
// Bridged Network
- String command = "vboxmanage list bridgedifs";
- String bridgedIfBlocks = context
- .getComputeService()
- .runScriptOnNode(hostId, command,
- runAsRoot(false).wrapInInitScript(false)).getOutput();
+ Statement command = Statements.exec("vboxmanage list bridgedifs");
+ String bridgedIfBlocks = runScriptOnNodeFactory.create(host, command, runAsRoot(false).wrapInInitScript(false))
+ .init().call().getOutput();
List<String> bridgedInterfaces = retrieveBridgedInterfaceNames(bridgedIfBlocks);
checkNotNull(bridgedInterfaces);
@@ -125,9 +126,8 @@
@Override
public boolean apply(String bridgedInterfaceName) {
try {
- return (bridgedInterfaceName.startsWith(networkInterface
- .getDisplayName()) && networkInterface.isUp() && !networkInterface
- .isLoopback());
+ return (bridgedInterfaceName.startsWith(networkInterface.getDisplayName()) && networkInterface.isUp() && !networkInterface
+ .isLoopback());
} catch (SocketException e) {
logger.error(e, "Problem in listing network interfaces.");
propagate(e);
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java
index d2608e8..0e80ec0 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttached.java
@@ -32,6 +32,7 @@
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
+import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
/**
@@ -44,12 +45,12 @@
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private VirtualBoxManager manager;
+ private Supplier<VirtualBoxManager> manager;
private String snapshotName;
private String snapshotDesc;
- public TakeSnapshotIfNotAlreadyAttached(VirtualBoxManager manager, String snapshotName, String snapshotDesc) {
+ public TakeSnapshotIfNotAlreadyAttached(Supplier<VirtualBoxManager> manager, String snapshotName, String snapshotDesc) {
this.manager = manager;
this.snapshotName = snapshotName;
this.snapshotDesc = snapshotDesc;
@@ -61,7 +62,7 @@
ISession session = null;
if(machine.getCurrentSnapshot() == null ) {
try {
- session = manager.openMachineSession(machine);
+ session = manager.get().openMachineSession(machine);
IProgress progress = session.getConsole().takeSnapshot(snapshotName, snapshotDesc);
if (progress.getCompleted())
logger.debug("Snapshot %s (description: %s) taken from %s", snapshotName, snapshotDesc, machine.getName());
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java
index e4f6953..ccf5cc1 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/FileDownloadFromURI.java
@@ -35,11 +35,10 @@
import javax.inject.Inject;
import javax.inject.Named;
-import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
-import org.jclouds.virtualbox.config.VirtualBoxConstants;
+import org.jclouds.rest.HttpClient;
import com.google.common.base.Function;
@@ -52,26 +51,22 @@
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private final ComputeServiceContext context;
+ private final HttpClient client;
private final String workingDir;
- private final String isoFile;
@Inject
- public FileDownloadFromURI(final ComputeServiceContext context,
- @Named(VIRTUALBOX_WORKINGDIR) final String workingDir,
- @Named(VirtualBoxConstants.VIRTUALBOX_ISOFILE) final String isoFile) {
- this.context = context;
+ public FileDownloadFromURI(HttpClient client, @Named(VIRTUALBOX_WORKINGDIR) String workingDir) {
+ this.client = client;
this.workingDir = workingDir;
- this.isoFile = isoFile;
}
@Override
public File apply(@Nullable URI input) {
- final File file = new File(workingDir, isoFile);
+ final File file = new File(workingDir, new File(input.getPath()).getName());
if (!file.exists()) {
- final InputStream inputStream = context.utils().http().get(input);
+ final InputStream inputStream = client.get(input);
checkNotNull(inputStream, "%s not found", input);
try {
copy(inputStream, new FileOutputStream(file));
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunning.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunning.java
index 9ca1b17..d5359b9 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunning.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunning.java
@@ -21,6 +21,10 @@
import static com.google.common.base.Preconditions.checkNotNull;
+import java.net.URI;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
@@ -31,51 +35,51 @@
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
-import org.jclouds.net.IPSocket;
-import org.jclouds.predicates.InetSocketAddressConnect;
+import org.jclouds.virtualbox.Preconfiguration;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
-import com.google.common.base.Function;
+import com.google.common.base.Supplier;
import com.google.inject.Singleton;
/**
* @author Andrea Turli
*/
-public class StartJettyIfNotAlreadyRunning implements Function<String, Server> {
+@Preconfiguration
+@Singleton
+public class StartJettyIfNotAlreadyRunning implements Supplier<URI> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
+ private final URI preconfigurationUrl;
private final Server jetty;
- private final int port;
- public StartJettyIfNotAlreadyRunning(Server jetty, @Named(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT) int port) {
- this.jetty = checkNotNull(jetty, "jetty");
- this.port = port;
- }
-
- // TODO: getting an instance of the Server object should really be done in
- // Guice, so inside a *Module class, perhaps as a @Provides method
@Inject
- public StartJettyIfNotAlreadyRunning(@Named(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT) int port) {
- this(ServerJetty.getInstance().getServer(), port);
+ public StartJettyIfNotAlreadyRunning(
+ @Named(VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
+ this(new Server(URI.create(preconfigurationUrl).getPort()), preconfigurationUrl);
}
- @Override
- public Server apply(@Nullable String baseResource) {
- if (!jetty.getState().equals(Server.STARTED)
- // TODO code smell = hard coding addresses or ports!!
- && !new InetSocketAddressConnect().apply(new IPSocket("localhost", port))) {
+ public StartJettyIfNotAlreadyRunning(Server jetty,
+ @Named(VirtualBoxConstants.VIRTUALBOX_PRECONFIGURATION_URL) String preconfigurationUrl) {
+ this.preconfigurationUrl = URI.create(checkNotNull(preconfigurationUrl, "preconfigurationUrl"));
+ this.jetty = jetty;
+ }
+
+ @PostConstruct
+ public void start() {
+
+ if (jetty.getState().equals(Server.STARTED)) {
+ logger.debug("not starting jetty, as existing host is serving %s", preconfigurationUrl);
+ } else {
+ logger.debug(">> starting jetty to serve %s", preconfigurationUrl);
ResourceHandler resource_handler = new ResourceHandler();
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[] { "index.html" });
- resource_handler.setResourceBase(baseResource);
- logger.info("serving " + resource_handler.getBaseResource());
-
+ resource_handler.setResourceBase("");
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
jetty.setHandler(handlers);
@@ -83,34 +87,23 @@
try {
jetty.start();
} catch (Exception e) {
- logger.error(e, "Server jetty could not be started at this %s", baseResource);
+ logger.error(e, "Server jetty could not be started for %s", preconfigurationUrl);
}
- return jetty;
- } else {
- logger.debug("Server jetty serving %s already running. Skipping start", baseResource);
- return jetty;
+ logger.debug("<< serving %s", resource_handler.getBaseResource());
}
}
- @Singleton
- private static class ServerJetty {
- private static ServerJetty instance;
- private Server server;
- private String port = System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080");
-
- private ServerJetty() {
- this.server = new Server(Integer.parseInt(port));
+ @PreDestroy()
+ public void stop() {
+ try {
+ jetty.stop();
+ } catch (Exception e) {
}
+ }
- public static ServerJetty getInstance() {
- if (instance == null)
- instance = new ServerJetty();
- return instance;
- }
-
- public Server getServer() {
- return server;
- }
+ @Override
+ public URI get() {
+ return preconfigurationUrl;
}
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java
index 59c4898..91edfcd 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunning.java
@@ -25,68 +25,84 @@
import java.net.URI;
+import javax.annotation.PostConstruct;
import javax.annotation.Resource;
+import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
-import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.domain.Credentials;
+import org.jclouds.location.Provider;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
+import org.jclouds.rest.annotations.Credential;
+import org.jclouds.rest.annotations.Identity;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
-public class StartVBoxIfNotAlreadyRunning implements Function<URI, VirtualBoxManager> {
+@Singleton
+public class StartVBoxIfNotAlreadyRunning implements Supplier<VirtualBoxManager> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private final ComputeService compute;
- private final VirtualBoxManager manager;
- private final Predicate<IPSocket> socketTester;
- private final String hostId;
- private final Credentials credentials;
+ private final Factory runScriptOnNodeFactory;
+ private final RetryIfSocketNotYetOpen socketTester;
+ private final Supplier<NodeMetadata> host;
+ private final URI provider;
+ private final String identity;
+ private final String credential;
+ private final Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode;
+ private transient VirtualBoxManager manager;
- public StartVBoxIfNotAlreadyRunning(ComputeService compute, VirtualBoxManager manager,
- Predicate<IPSocket> socketTester, String hostId, Credentials credentials) {
- this.compute = checkNotNull(compute, "compute");
- this.manager = checkNotNull(manager, "manager");
+ // the functions and suppliers here are to ensure we don't do heavy i/o in injection
+ @Inject
+ public StartVBoxIfNotAlreadyRunning(Function<Supplier<NodeMetadata>, VirtualBoxManager> managerForNode,
+ Factory runScriptOnNodeFactory, RetryIfSocketNotYetOpen socketTester, Supplier<NodeMetadata> host,
+ @Provider URI provider, @Identity String identity, @Credential String credential) {
+ this.runScriptOnNodeFactory = checkNotNull(runScriptOnNodeFactory, "runScriptOnNodeFactory");
this.socketTester = checkNotNull(socketTester, "socketTester");
- this.hostId = checkNotNull(hostId, "hostId");
- this.credentials = checkNotNull(credentials, "credentials");
+ this.host = checkNotNull(host, "host");
+ this.provider = checkNotNull(provider, "endpoint to virtualbox websrvd is needed");
+ this.identity = checkNotNull(identity, "identity");
+ this.credential = checkNotNull(credential, "credential");
+ this.managerForNode = checkNotNull(managerForNode, "managerForNode");
+ }
+
+ @PostConstruct
+ public void start() {
+ if (!socketTester.apply(new IPSocket(provider.getHost(), provider.getPort()))) {
+ logger.debug("disabling password access");
+ runScriptOnNodeFactory.create(host.get(), Statements.exec("VBoxManage setproperty websrvauthlibrary null"),
+ runAsRoot(false).wrapInInitScript(false)).init().call();
+ logger.debug(">> starting vboxwebsrv");
+ String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
+ if (host.get().getOperatingSystem() != null
+ && host.get().getOperatingSystem().getDescription().equals("Mac OS X"))
+ vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
+
+ runScriptOnNodeFactory.create(host.get(), Statements.exec(vboxwebsrv),
+ runAsRoot(false).wrapInInitScript(false).blockOnComplete(false).nameTask("vboxwebsrv")).init().call();
+ }
+ manager = managerForNode.apply(host);
+ manager.connect(provider.toASCIIString(), identity, credential);
+ if (logger.isDebugEnabled())
+ if (manager.getSessionObject().getState() == SessionState.Unlocked)
+ logger.warn("manager is not in unlocked state " + manager);
}
@Override
- public VirtualBoxManager apply(URI endpoint) {
- checkState(compute.getNodeMetadata(hostId) != null, "compute service %s cannot locate node with id %s", compute,
- hostId);
- checkNotNull(endpoint, "endpoint to virtualbox websrvd is needed");
-
- if (socketTester.apply(new IPSocket(endpoint.getHost(), endpoint.getPort()))) {
- manager.connect(endpoint.toASCIIString(), credentials.identity, credentials.credential);
- return manager;
- }
-
- logger.debug("disabling password access");
- compute.runScriptOnNode(hostId, "VBoxManage setproperty websrvauthlibrary null", runAsRoot(false)
- .wrapInInitScript(false));
- logger.debug("starting vboxwebsrv");
- String vboxwebsrv = "vboxwebsrv -t 10000 -v -b";
- if (isOSX(hostId))
- vboxwebsrv = "cd /Applications/VirtualBox.app/Contents/MacOS/ && " + vboxwebsrv;
-
- compute.runScriptOnNode(hostId, vboxwebsrv, runAsRoot(false).wrapInInitScript(false).blockOnComplete(false)
- .nameTask("vboxwebsrv"));
-
- manager.connect(endpoint.toASCIIString(), credentials.identity, credentials.credential);
+ public VirtualBoxManager get() {
+ checkState(manager != null, "start not called");
return manager;
}
- private boolean isOSX(String hostId) {
- return compute.getNodeMetadata(hostId).getOperatingSystem().getDescription().equals("Mac OS X");
- }
-
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java
index be862bb..ce02937 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMedia.java
@@ -1,3 +1,21 @@
+/**
+ * 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.
+ */
/*
U * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
@@ -20,77 +38,74 @@
package org.jclouds.virtualbox.functions.admin;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
import java.util.Collections;
import java.util.List;
import javax.annotation.Resource;
import javax.inject.Named;
+import javax.inject.Singleton;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.virtualbox.domain.ErrorCode;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
+import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.VBoxException;
-import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-public class UnregisterMachineIfExistsAndDeleteItsMedia implements
- Function<VmSpec, Void> {
+@Singleton
+public class UnregisterMachineIfExistsAndDeleteItsMedia implements Function<IMachine, Void> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
- private VirtualBoxManager manager;
+ private final VmSpec vmSpec;
- public UnregisterMachineIfExistsAndDeleteItsMedia(VirtualBoxManager manager) {
- this.manager = manager;
+ public UnregisterMachineIfExistsAndDeleteItsMedia(VmSpec vmSpec) {
+ this.vmSpec = vmSpec;
}
@Override
- public Void apply(VmSpec vmSpec) {
+ public Void apply(IMachine machine) {
List<IMedium> mediaToBeDeleted = Collections.emptyList();
- IMachine machine = null;
try {
- machine = manager.getVBox().findMachine(vmSpec.getVmName());
mediaToBeDeleted = machine.unregister(vmSpec.getCleanupMode());
} catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e);
switch (errorCode) {
- case VBOX_E_OBJECT_NOT_FOUND:
- logger.debug("Machine %s does not exists, cannot unregister",
- vmSpec.getVmName());
- break;
- default:
- throw e;
+ case VBOX_E_OBJECT_NOT_FOUND:
+ logger.debug("Machine %s does not exists, cannot unregister", vmSpec.getVmName());
+ break;
+ default:
+ throw e;
}
}
- List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(Iterables
- .filter(mediaToBeDeleted, new AutoDeleteHardDiskPredicate(vmSpec)));
+ List<IMedium> filteredMediaToBeDeleted = Lists.newArrayList(transform(filter(mediaToBeDeleted,
+ new AutoDeleteHardDiskPredicate(vmSpec)), new DeleteChildrenOfMedium()));
- checkNotNull(filteredMediaToBeDeleted);
if (!filteredMediaToBeDeleted.isEmpty()) {
try {
IProgress deletion = machine.delete(filteredMediaToBeDeleted);
deletion.waitForCompletion(-1);
-
} catch (Exception e) {
- logger.error(e, "Problem in deleting the media attached to %s",
- machine.getName());
+ logger.error(e, "Problem in deleting the media attached to %s", machine.getName());
Throwables.propagate(e);
}
}
+
return null;
}
@@ -113,4 +128,19 @@
};
+ private class DeleteChildrenOfMedium implements Function<IMedium, IMedium> {
+ @Override
+ public IMedium apply(IMedium medium) {
+ checkNotNull(medium.getChildren());
+ if (medium.getDeviceType().equals(DeviceType.HardDisk)) {
+ for (IMedium child : medium.getChildren()) {
+ IProgress deletion = child.deleteStorage();
+ deletion.waitForCompletion(-1);
+ }
+ }
+ return medium;
+ }
+
+ };
+
}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IsLinkedClone.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IsLinkedClone.java
new file mode 100644
index 0000000..afb95ac
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/IsLinkedClone.java
@@ -0,0 +1,92 @@
+/**
+ * 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.virtualbox.predicates;
+
+import javax.annotation.Nullable;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.virtualbox_4_1.DeviceType;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IMediumAttachment;
+import org.virtualbox_4_1.IStorageController;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+
+/**
+ *
+ * @author Andrea Turli
+ */
+@Singleton
+public class IsLinkedClone implements Predicate<IMachine> {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier<VirtualBoxManager> manager;
+
+ @Inject
+ public IsLinkedClone(Supplier<VirtualBoxManager> manager) {
+ this.manager = manager;
+ }
+
+ @Override
+ public boolean apply(@Nullable IMachine machine) {
+
+ for (IStorageController iStorageController : machine
+ .getStorageControllers()) {
+
+ for (IMediumAttachment iMediumAttachment : machine
+ .getMediumAttachmentsOfController(iStorageController.getName())) {
+ IMedium iMedium = iMediumAttachment.getMedium();
+ if (iMedium.getDeviceType().equals(DeviceType.HardDisk)) {
+ if (iMedium.getParent() != null) {
+ // more than one machine is attached to this hd
+ for (IMedium child : iMedium.getParent().getChildren()) {
+ for (String machineId : child.getMachineIds()) {
+ IMachine iMachine = manager.get().getVBox().findMachine(
+ machineId);
+ if (!iMachine.getName().equals(machine.getName())) {
+ logger.debug("Machine %s is a linked clone",
+ machine.getName());
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "IsLinkedClone()";
+ }
+
+}
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java
index 4be1bf7..ffede70 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshAvailable.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.predicates;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshResponds.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshResponds.java
new file mode 100644
index 0000000..676f42a
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/predicates/SshResponds.java
@@ -0,0 +1,52 @@
+/**
+ * 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.virtualbox.predicates;
+
+import javax.annotation.Resource;
+
+import org.jclouds.logging.Logger;
+import org.jclouds.ssh.SshClient;
+import org.jclouds.ssh.SshException;
+
+import com.google.common.base.Predicate;
+
+/**
+ *
+ * @author Adrian Cole
+ */
+public class SshResponds implements Predicate<SshClient> {
+ @Resource
+ protected Logger logger = Logger.NULL;
+
+ @Override
+ public boolean apply(SshClient client) {
+
+ try {
+ client.connect();
+ if (client.exec("id").getExitCode() == 0) {
+ return true;
+ }
+ } catch (SshException e) {
+ logger.trace("No response from ssh daemon connecting to %s: %s", client, e.getMessage());
+ } finally {
+ client.disconnect();
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
index 9a5660d..123646c 100644
--- a/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
+++ b/sandbox-apis/virtualbox/src/main/java/org/jclouds/virtualbox/util/MachineUtils.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,21 +16,91 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.util;
+import static org.jclouds.scriptbuilder.domain.Statements.call;
+import static org.jclouds.scriptbuilder.domain.Statements.findPid;
+import static org.jclouds.scriptbuilder.domain.Statements.kill;
+import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.scriptbuilder.domain.OsFamily;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.util.Throwables2;
+import org.jclouds.virtualbox.functions.MutableMachine;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.ISession;
+import org.virtualbox_4_1.LockType;
+import org.virtualbox_4_1.SessionState;
+import org.virtualbox_4_1.VBoxException;
+import org.virtualbox_4_1.VirtualBoxManager;
+
import com.google.common.base.Function;
-import org.virtualbox_4_1.*;
+import com.google.common.base.Functions;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
/**
* Utilities for executing functions on a VirtualBox machine.
- *
- * @author Adrian Cole, Mattias Holmqvist
+ *
+ * @author Adrian Cole, Mattias Holmqvist, Andrea Turli
*/
+
+@Singleton
public class MachineUtils {
- public static <T> T applyForMachine(VirtualBoxManager manager, final String machineId, final Function<IMachine, T> function) {
- final IMachine immutableMachine = manager.getVBox().findMachine(machineId);
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier<VirtualBoxManager> manager;
+ private final LockType lockType;
+ private final Factory scriptRunner;
+ private final Supplier<NodeMetadata> host;
+
+ @Inject
+ public MachineUtils(Supplier<VirtualBoxManager> manager, LockType lockType, RunScriptOnNode.Factory scriptRunner, Supplier<NodeMetadata> host) {
+ super();
+ this.manager = manager;
+ this.lockType = lockType;
+ this.scriptRunner = scriptRunner;
+ this.host = host;
+ }
+
+ public <T> Function<String, T> mutateMachine(String machineId,
+ Function<IMachine, T> function) {
+ try {
+ return Functions.compose(function, new MutableMachine(manager, lockType));
+ } finally {
+ unlockMachine(machineId);
+ }
+ }
+
+ protected void unlockMachine(final String machineId) {
+ IMachine immutableMachine = manager.get().getVBox().findMachine(machineId);
+ if (immutableMachine.getSessionState().equals(SessionState.Locked)) {
+ Statement kill = newStatementList(call("default"),
+ findPid(immutableMachine.getSessionPid().toString()), kill());
+ scriptRunner
+ .create(host.get(), kill,
+ runAsRoot(false).wrapInInitScript(false)).init().call();
+ }
+ }
+
+ public static <T> T applyForMachine(VirtualBoxManager manager,
+ final String machineId, final Function<IMachine, T> function) {
+ final IMachine immutableMachine = manager.getVBox()
+ .findMachine(machineId);
return new Function<IMachine, T>() {
@Override
public T apply(IMachine machine) {
@@ -45,48 +115,60 @@
}
/**
- * Locks the machine and executes the given function using the machine matching the given id.
- * Since the machine is locked it is possible to perform some modifications to the IMachine.
+ * Locks the machine and executes the given function using the machine
+ * matching the given id. Since the machine is locked it is possible to
+ * perform some modifications to the IMachine.
* <p/>
* Unlocks the machine before returning.
- *
- * @param manager the VirtualBoxManager
- * @param type the kind of lock to use when initially locking the machine.
- * @param machineId the id of the machine
- * @param function the function to execute
+ *
+ * @param manager
+ * the VirtualBoxManager
+ * @param type
+ * the kind of lock to use when initially locking the machine.
+ * @param machineId
+ * the id of the machine
+ * @param function
+ * the function to execute
* @return the result from applying the function to the machine.
*/
- public static <T> T lockMachineAndApply(VirtualBoxManager manager, final LockType type, final String machineId,
- final Function<IMachine, T> function) {
- return lockSessionOnMachineAndApply(manager, type, machineId, new Function<ISession, T>() {
+ public static <T> T lockMachineAndApply(VirtualBoxManager manager,
+ final LockType type, final String machineId,
+ final Function<IMachine, T> function) {
+ return lockSessionOnMachineAndApply(manager, type, machineId,
+ new Function<ISession, T>() {
- @Override
- public T apply(ISession session) {
- return function.apply(session.getMachine());
- }
+ @Override
+ public T apply(ISession session) {
+ return function.apply(session.getMachine());
+ }
- @Override
- public String toString() {
- return function.toString();
- }
+ @Override
+ public String toString() {
+ return function.toString();
+ }
- });
+ });
}
/**
- * Locks the machine and executes the given function using the current session.
- * Since the machine is locked it is possible to perform some modifications to the IMachine.
+ * Locks the machine and executes the given function using the current
+ * session. Since the machine is locked it is possible to perform some
+ * modifications to the IMachine.
* <p/>
* Unlocks the machine before returning.
- *
- * @param manager the VirtualBoxManager
- * @param type the kind of lock to use when initially locking the machine.
- * @param machineId the id of the machine
- * @param function the function to execute
+ *
+ * @param manager
+ * the VirtualBoxManager
+ * @param type
+ * the kind of lock to use when initially locking the machine.
+ * @param machineId
+ * the id of the machine
+ * @param function
+ * the function to execute
* @return the result from applying the function to the session.
*/
- public static <T> T lockSessionOnMachineAndApply(VirtualBoxManager manager, LockType type, String machineId,
- Function<ISession, T> function) {
+ public static <T> T lockSessionOnMachineAndApply(VirtualBoxManager manager,
+ LockType type, String machineId, Function<ISession, T> function) {
try {
ISession session = manager.getSessionObject();
IMachine immutableMachine = manager.getVBox().findMachine(machineId);
@@ -97,8 +179,111 @@
session.unlockMachine();
}
} catch (VBoxException e) {
- throw new RuntimeException(String.format("error applying %s to %s with %s lock: %s", function, machineId,
- type, e.getMessage()), e);
+ throw new RuntimeException(String.format(
+ "error applying %s to %s with %s lock: %s", function, machineId,
+ type, e.getMessage()), e);
+ }
+ }
+
+ /**
+ * Locks the machine and executes the given function using the current
+ * session, if the machine is registered. Since the machine is locked it is
+ * possible to perform some modifications to the IMachine.
+ * <p/>
+ * Unlocks the machine before returning.
+ *
+ * @param manager
+ * the VirtualBoxManager
+ * @param type
+ * the kind of lock to use when initially locking the machine.
+ * @param machineId
+ * the id of the machine
+ * @param function
+ * the function to execute
+ * @return the result from applying the function to the session.
+ */
+ public static <T> T lockMachineAndApplyOrReturnNullIfNotRegistered(
+ VirtualBoxManager manager, LockType type, String machineId,
+ Function<IMachine, T> function) {
+ try {
+ return lockMachineAndApply(manager, type, machineId, function);
+ } catch (RuntimeException e) {
+ VBoxException vbex = Throwables2.getFirstThrowableOfType(e,
+ VBoxException.class);
+ if (vbex != null
+ && vbex.getMessage().indexOf("not find a registered") == -1)
+ throw e;
+ return null;
+ }
+ }
+
+ /**
+ * Unlocks the machine and executes the given function using the machine
+ * matching the given id. Since the machine is unlocked it is possible to
+ * delete the IMachine.
+ * <p/>
+ *
+ * <h3>Note!</h3> Currently, this can only unlock the machine, if the lock
+ * was created in the current session.
+ *
+ * @param manager
+ * the VirtualBoxManager
+ * @param machineId
+ * the id of the machine
+ * @param function
+ * the function to execute
+ * @return the result from applying the function to the machine.
+ */
+ public static <T> T unlockMachineAndApply(VirtualBoxManager manager,
+ final String machineId, final Function<IMachine, T> function) {
+ ISession session = manager.getSessionObject();
+
+ try {
+ IMachine immutableMachine = manager.getVBox().findMachine(machineId);
+ SessionState state = immutableMachine.getSessionState();
+ Statement kill = newStatementList(call("default"),
+ findPid(immutableMachine.getSessionPid().toString()), kill());
+ if (state.equals(SessionState.Locked))
+ // session.unlockMachine();
+ kill.render(OsFamily.UNIX);
+ // TODO: wire this in
+
+ return function.apply(immutableMachine);
+
+ } catch (VBoxException e) {
+ session.unlockMachine();
+ throw new RuntimeException(String.format(
+ "error applying %s to %s: %s", function, machineId,
+ e.getMessage()), e);
+ }
+ }
+
+ /**
+ * Unlocks the machine and executes the given function, if the machine is
+ * registered. Since the machine is unlocked it is possible to delete the
+ * machine.
+ * <p/>
+ *
+ * @param manager
+ * the VirtualBoxManager
+ * @param machineId
+ * the id of the machine
+ * @param function
+ * the function to execute
+ * @return the result from applying the function to the session.
+ */
+ public static <T> T unlockMachineAndApplyOrReturnNullIfNotRegistered(
+ VirtualBoxManager manager, String machineId,
+ Function<IMachine, T> function) {
+ try {
+ return unlockMachineAndApply(manager, machineId, function);
+ } catch (RuntimeException e) {
+ VBoxException vbex = Throwables2.getFirstThrowableOfType(e,
+ VBoxException.class);
+ if (vbex != null
+ && vbex.getMessage().indexOf("not find a registered") == -1)
+ throw e;
+ return null;
}
}
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
index 9bb431f..99f8307 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/BaseVirtualBoxClientLiveTest.java
@@ -19,93 +19,125 @@
package org.jclouds.virtualbox;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
+import static org.jclouds.virtualbox.util.MachineUtils.unlockMachineAndApplyOrReturnNullIfNotRegistered;
import java.net.URI;
import java.util.Properties;
-import org.eclipse.jetty.server.Server;
+import org.jclouds.Constants;
+import org.jclouds.byon.Node;
+import org.jclouds.byon.config.CacheNodeStoreModule;
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
-import org.jclouds.domain.Credentials;
-import org.jclouds.logging.log4j.config.Log4JLoggingModule;
-import org.jclouds.predicates.InetSocketAddressConnect;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.config.ValueOfConfigurationKeyOrNull;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.virtualbox.config.VirtualBoxConstants;
-import org.jclouds.virtualbox.functions.admin.StartJettyIfNotAlreadyRunning;
-import org.jclouds.virtualbox.functions.admin.StartVBoxIfNotAlreadyRunning;
-import org.testng.annotations.AfterGroups;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.jclouds.virtualbox.functions.CreateAndInstallVm;
+import org.jclouds.virtualbox.functions.CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
+import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
+import org.jclouds.virtualbox.util.MachineUtils;
+import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
-import org.virtualbox_4_1.SessionState;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.inject.Key;
import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code VirtualBoxClient}
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class BaseVirtualBoxClientLiveTest {
-
- protected String provider = "virtualbox";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint", "http://localhost:18083/");
- apiversion = System.getProperty("test." + provider + ".apiversion", "4.1.2r73507");
+@Test(groups = "live", singleThreaded = true, testName = "BaseVirtualBoxClientLiveTest")
+public class BaseVirtualBoxClientLiveTest extends BaseVersionedServiceLiveTest {
+ public BaseVirtualBoxClientLiveTest() {
+ provider = "virtualbox";
}
protected ComputeServiceContext context;
- protected VirtualBoxManager manager;
- protected Server jetty;
+ protected Supplier<VirtualBoxManager> manager;
+ protected Supplier<URI> preconfigurationUri;
+ protected String hostVersion;
+ protected String operatingSystemIso;
+ protected String guestAdditionsIso;
+ protected String adminDisk;
+ protected String workingDir;
+ protected Supplier<NodeMetadata> host;
- @BeforeGroups(groups = { "live" })
- public void setupClient() {
- Properties properties = new Properties();
- properties.setProperty(provider + ".endpoint", endpoint);
- properties.setProperty(provider + ".apiversion", apiversion);
- context = new ComputeServiceContextFactory().createContext(provider, identity, credential,
- ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
- jetty = new StartJettyIfNotAlreadyRunning(port).apply(basebaseResource);
- startVboxIfNotAlreadyRunning();
+ @Override
+ protected void setupCredentials() {
+ // default behavior is to bomb when no user is configured, but we know the default user of
+ // vbox
+ ensureIdentityPropertyIsSpecifiedOrTakeFromDefaults();
+ super.setupCredentials();
}
- @AfterGroups(groups = "live")
+ protected void ensureIdentityPropertyIsSpecifiedOrTakeFromDefaults() {
+ Properties defaultVBoxProperties = new VirtualBoxPropertiesBuilder().build();
+ if (!System.getProperties().containsKey("test." + provider + ".identity"))
+ System.setProperty("test." + provider + ".identity", defaultVBoxProperties
+ .getProperty(Constants.PROPERTY_IDENTITY));
+ }
+
+ @BeforeClass(groups = "live")
+ public void setupClient() {
+ setupCredentials();
+ Properties overrides = setupProperties();
+
+ CacheNodeStoreModule hostModule = new CacheNodeStoreModule(ImmutableMap.of("host", Node.builder().id("host")
+ .name("host installing virtualbox").hostname("localhost").osFamily(OsFamily.LINUX.toString())
+ .osDescription(System.getProperty("os.name")).osVersion(System.getProperty("os.version")).group("ssh")
+ .username(System.getProperty("user.name")).credentialUrl(
+ URI.create("file://" + System.getProperty("user.home") + "/.ssh/id_rsa")).build()));
+
+ context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet
+ .<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule(), hostModule), overrides);
+ Function<String, String> configProperties = context.utils().injector().getInstance(
+ ValueOfConfigurationKeyOrNull.class);
+ imageId = configProperties.apply(ComputeServiceConstants.PROPERTY_IMAGE_ID);
+ workingDir = configProperties.apply(VirtualBoxConstants.VIRTUALBOX_WORKINGDIR);
+ host = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<NodeMetadata>>(){}));
+
+ // this will eagerly startup Jetty, note the impl will shut itself down
+ preconfigurationUri = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<URI>>() {
+ }, Preconfiguration.class));
+ // this will eagerly startup Jetty, note the impl will shut itself down
+ preconfigurationUri.get();
+
+ manager = context.utils().injector().getInstance(Key.get(new TypeLiteral<Supplier<VirtualBoxManager>>() {
+ }));
+ // this will eagerly startup vbox
+ manager.get();
+
+ hostVersion = Iterables.get(Splitter.on('r').split(context.getProviderSpecificContext().getBuildVersion()), 0);
+ adminDisk = workingDir + "/testadmin.vdi";
+ operatingSystemIso = String.format("%s/%s.iso", workingDir, imageId);
+ guestAdditionsIso = String.format("%s/VBoxGuestAdditions_%s.iso", workingDir, hostVersion);
+ }
+
+ protected void undoVm(VmSpec vmSpecification) {
+ MachineUtils machineUtils = context.utils().injector().getInstance(MachineUtils.class);
+ machineUtils.mutateMachine(vmSpecification.getVmId(), new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification));
+ }
+
+ @AfterClass(groups = "live")
protected void tearDown() throws Exception {
if (context != null)
context.close();
- if (jetty != null)
- jetty.stop();
- // TODO: should we stop the vbox manager?
}
- private String basebaseResource = ".";
- // TODO: I'd not use 8080, maybe something like 28080
- // also update pom.xml so that this passes through
- private int port = Integer.parseInt(System.getProperty(VirtualBoxConstants.VIRTUALBOX_JETTY_PORT, "8080"));
-
- protected void startVboxIfNotAlreadyRunning() {
- Credentials localhostCredentials = new Credentials("toor", "password");
- ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest("hostId", "localhost", "guestId",
- "localhost", localhostCredentials);
-
- manager = new StartVBoxIfNotAlreadyRunning(localHostContext.getComputeService(),
- VirtualBoxManager.createInstance("hostId"), new InetSocketAddressConnect(), "hostId", localhostCredentials)
- .apply(URI.create(endpoint));
-
- assert manager.getSessionObject().getState() == SessionState.Unlocked : "manager needs to be in unlocked state or all tests will fail!!: "
- + manager;
- }
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
index 0bb1f68..a2f8a2e 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterLiveTest.java
@@ -21,58 +21,33 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
-
-import java.net.URI;
-import java.util.Map;
+import static org.testng.Assert.assertTrue;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
-import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
-import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Credentials;
-import org.jclouds.json.Json;
-import org.jclouds.json.config.GsonModule;
-import org.jclouds.location.suppliers.JustProvider;
import org.jclouds.net.IPSocket;
import org.jclouds.ssh.SshClient;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
-import org.jclouds.virtualbox.functions.IMachineToImage;
-import org.testng.annotations.AfterGroups;
-import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine;
-import org.virtualbox_4_1.VirtualBoxManager;
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
-import com.google.inject.Guice;
@Test(groups = "live", singleThreaded = true, testName = "VirtualBoxComputeServiceAdapterLiveTest")
public class VirtualBoxComputeServiceAdapterLiveTest extends BaseVirtualBoxClientLiveTest {
private VirtualBoxComputeServiceAdapter adapter;
private NodeAndInitialCredentials<IMachine> machine;
- private final Map<OsFamily, Map<String, String>> osVersionMap = new BaseComputeServiceContextModule() {
- }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
- .getInstance(Json.class));
- @BeforeGroups(groups = { "live" })
+ @Override
public void setupClient() {
super.setupClient();
- final VirtualBoxManager manager = getManager();
- Function<IMachine, Image> iMachineToImage = new IMachineToImage(manager, osVersionMap);
- adapter = new VirtualBoxComputeServiceAdapter(manager, new JustProvider(provider, URI.create(endpoint),
- ImmutableSet.<String> of()), iMachineToImage);
- }
-
- protected VirtualBoxManager getManager() {
- return (VirtualBoxManager) context.getProviderSpecificContext().getApi();
+ adapter = context.utils().injector().getInstance(VirtualBoxComputeServiceAdapter.class);
}
@Test
@@ -120,7 +95,7 @@
@Test
public void testListHardwareProfiles() {
Iterable<IMachine> profiles = adapter.listHardwareProfiles();
- assertFalse(Iterables.isEmpty(profiles));
+ assertTrue(Iterables.isEmpty(profiles));
// check state;
}
@@ -132,8 +107,8 @@
}
// check state;
}
-
- @AfterGroups(groups = "live")
+
+ @Override
protected void tearDown() throws Exception {
if (machine != null)
adapter.destroyNode(machine.getNodeId() + "");
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterTest.java
index 71d6a4f..b22fb76 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapterTest.java
@@ -46,6 +46,7 @@
import org.virtualbox_4_1.VirtualBoxManager;
import com.google.common.base.Function;
+import com.google.common.base.Suppliers;
import com.google.common.collect.Iterators;
import com.google.inject.Guice;
@@ -83,8 +84,8 @@
replay(manager, justProvider, vBox, clonedMachine, imageMachine, osType);
- Function<IMachine, Image> iMachineToImage = new IMachineToImage(manager, osMap);
- VirtualBoxComputeServiceAdapter adapter = new VirtualBoxComputeServiceAdapter(manager, justProvider,
+ Function<IMachine, Image> iMachineToImage = new IMachineToImage(Suppliers.ofInstance(manager), osMap);
+ VirtualBoxComputeServiceAdapter adapter = new VirtualBoxComputeServiceAdapter(Suppliers.ofInstance(manager), justProvider,
iMachineToImage);
Iterator<Image> iterator = adapter.listImages().iterator();
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/domain/InstallGuestAdditionsTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/domain/InstallGuestAdditionsTest.java
index 065d5aa..675e2db 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/domain/InstallGuestAdditionsTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/domain/InstallGuestAdditionsTest.java
@@ -1,3 +1,21 @@
+/**
+ * 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.virtualbox.domain;
import static org.testng.Assert.assertEquals;
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java
deleted file mode 100644
index c7d265b..0000000
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/experiment/TestUtils.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * 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.virtualbox.experiment;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Map;
-
-import org.jclouds.byon.Node;
-import org.jclouds.byon.config.CacheNodeStoreModule;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.ComputeServiceContextFactory;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.domain.Credentials;
-import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.sshj.config.SshjSshClientModule;
-
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Module;
-
-public class TestUtils {
-
- public static ComputeServiceContext computeServiceForLocalhostAndGuest() throws IOException {
-
- Node host = Node.builder().id("host").name("host installing virtualbox").hostname("localhost")
- .osFamily(OsFamily.LINUX.toString()).osDescription(System.getProperty("os.name"))
- .osVersion(System.getProperty("os.version")).group("ssh").username(System.getProperty("user.name"))
- .credentialUrl(privateKeyFile()).build();
- Node guest = Node.builder().id("guest").name("new guest").hostname("localhost").loginPort(2222)
- .osFamily(OsFamily.UBUNTU.toString()).osDescription("ubuntu/11.04").osVersion(System.getProperty("11.04"))
- .group("guest").username("toor").sudoPassword("password").credential("password").build();
-
- final Map<String, Node> nodeMap = ImmutableMap.<String, Node> builder().put("host", host).put("guest", guest)
- .build();
- return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.<Module> of(
- new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(),
- new CacheNodeStoreModule(nodeMap)));
- }
-
- public static ComputeServiceContext computeServiceForLocalhostAndGuest(String hostId, String hostname,
- String guestId, String guestHostname, Credentials guestLogin) {
-
- Node host = Node.builder().id(hostId).name("host installing virtualbox").hostname(hostname)
- .osFamily(OsFamily.LINUX.toString()).osDescription(System.getProperty("os.name"))
- .osVersion(System.getProperty("os.version")).group("ssh").username(System.getProperty("user.name"))
- .credentialUrl(privateKeyFile()).build();
- Node guest = Node.builder().id(guestId).name("new guest").hostname(guestHostname).loginPort(2222)
- .osFamily(OsFamily.UBUNTU.toString()).osDescription("ubuntu/11.04").osVersion(System.getProperty("11.04"))
- .group("jclouds-linux-image").username(guestLogin.identity).sudoPassword(guestLogin.credential)
- .credential(guestLogin.credential).build();
-
- final Map<String, Node> nodeMap = ImmutableMap.<String, Node> builder().put(hostId, host).put(guestId, guest)
- .build();
- return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.<Module> of(
- new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(),
- new CacheNodeStoreModule(nodeMap)));
- }
-
- private static URI privateKeyFile() {
- try {
- return new URI("file://" + System.getProperty("user.home") + "/.ssh/id_rsa");
- } catch (URISyntaxException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public static ComputeServiceContext computeServiceForVirtualBox(LoadingCache<String, Node> cache) {
- return new ComputeServiceContextFactory().createContext("byon", "foo", "bar", ImmutableSet.<Module> of(
- new SshjSshClientModule(), new SLF4JLoggingModule(), new BouncyCastleCryptoModule(),
- new CacheNodeStoreModule(cache)));
- }
-}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java
index 777949e..a85789c 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachBridgedAdapterToMachineTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.easymock.EasyMock.expect;
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachMediumToMachineIfNotAlreadyAttachedTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachMediumToMachineIfNotAlreadyAttachedTest.java
index 7b1266b..b0843f1 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachMediumToMachineIfNotAlreadyAttachedTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachMediumToMachineIfNotAlreadyAttachedTest.java
@@ -52,7 +52,6 @@
String controllerName = "IDE Controller";
String diskPath = "/Users/johndoe/jclouds-virtualbox-images/admin.vdi";
- String diskName = "admin";
String diskFormat = "vdi";
int controllerPort = 0;
int deviceSlot = 1;
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java
similarity index 61%
rename from sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineTest.java
rename to sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java
index 39375e0..a778e7d 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/AttachNATAdapterToMachineIfNotAlreadyExistsTest.java
@@ -19,6 +19,14 @@
package org.jclouds.virtualbox.functions;
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.createNiceMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+import static org.virtualbox_4_1.NATProtocol.TCP;
+import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
+
import org.jclouds.virtualbox.domain.NatAdapter;
import org.testng.annotations.Test;
import org.virtualbox_4_1.IMachine;
@@ -26,16 +34,11 @@
import org.virtualbox_4_1.INetworkAdapter;
import org.virtualbox_4_1.VBoxException;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.classextension.EasyMock.*;
-import static org.virtualbox_4_1.NATProtocol.TCP;
-import static org.virtualbox_4_1.NetworkAttachmentType.NAT;
-
/**
* @author Mattias Holmqvist
*/
-@Test(groups = "unit", testName = "AttachNATAdapterToMachineTest")
-public class AttachNATAdapterToMachineTest {
+@Test(groups = "unit", testName = "AttachNATAdapterToMachineIfNotAlreadyExistsTest")
+public class AttachNATAdapterToMachineIfNotAlreadyExistsTest {
@Test
public void testApplyNetworkingToNonExistingAdapter() throws Exception {
@@ -47,17 +50,43 @@
expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter);
networkAdapter.setAttachmentType(NAT);
expect(networkAdapter.getNatDriver()).andReturn(natEngine);
- natEngine.addRedirect("guestssh", TCP, "127.0.0.1", 2222, "", 22);
+
+ natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", 2222, "", 22);
networkAdapter.setEnabled(true);
machine.saveSettings();
replay(machine, networkAdapter, natEngine);
NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
- new AttachNATAdapterToMachine(slotId, natAdapter).apply(machine);
+ new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
verify(machine, networkAdapter, natEngine);
}
+ @Test
+ public void testApplySkipsWhenAlreadyExists() throws Exception {
+ Long slotId = 0l;
+ IMachine machine = createMock(IMachine.class);
+ INetworkAdapter networkAdapter = createMock(INetworkAdapter.class);
+ INATEngine natEngine = createMock(INATEngine.class);
+
+ expect(machine.getNetworkAdapter(slotId)).andReturn(networkAdapter);
+ networkAdapter.setAttachmentType(NAT);
+ expect(networkAdapter.getNatDriver()).andReturn(natEngine);
+
+ natEngine.addRedirect("TCP@127.0.0.1:2222->:22", TCP, "127.0.0.1", 2222, "", 22);
+ expectLastCall().andThrow(
+ new VBoxException(null, "VirtualBox error: A NAT rule of this name already exists (0x80070057)"));
+
+ networkAdapter.setEnabled(true);
+ machine.saveSettings();
+
+ replay(machine, networkAdapter, natEngine);
+ NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
+ new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
+
+ verify(machine, networkAdapter, natEngine);
+ }
+
@Test(expectedExceptions = VBoxException.class)
public void testRethrowInvalidAdapterSlotException() throws Exception {
Long slotId = 30l;
@@ -74,7 +103,7 @@
replay(machine, networkAdapter, natEngine);
NatAdapter natAdapter = NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build();
- new AttachNATAdapterToMachine(slotId, natAdapter).apply(machine);
+ new AttachNATAdapterToMachineIfNotAlreadyExists(slotId, natAdapter).apply(machine);
verify(machine, networkAdapter, natEngine);
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
index ad96033..d4558d1 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
@@ -19,31 +19,22 @@
package org.jclouds.virtualbox.functions;
-import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS;
-import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import static org.testng.Assert.assertEquals;
-import static org.virtualbox_4_1.NetworkAttachmentType.Bridged;
-import java.util.concurrent.TimeUnit;
-
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.domain.Credentials;
-import org.jclouds.net.IPSocket;
-import org.jclouds.predicates.InetSocketAddressConnect;
-import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
-import org.jclouds.virtualbox.util.PropertyUtils;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.StorageBus;
-import org.virtualbox_4_1.VirtualBoxManager;
-import com.google.common.base.Predicate;
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ImmutableSet;
/**
* @author Andrea Turli
@@ -51,59 +42,63 @@
@Test(groups = "live", singleThreaded = true, testName = "CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest")
public class CloneAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest {
- private String settingsFile = null;
- private boolean forceOverwrite = true;
- private String vmId = "jclouds-image-iso-1";
- private String osTypeId = "";
- private String controllerIDE = "IDE Controller";
- private String guestId = "guest";
- private String hostId = "host";
- private String snapshotName = "snap";
- private String snapshotDesc = "snapDesc";
+ private static final boolean IS_LINKED_CLONE = true;
- private String vmName = "jclouds-image-virtualbox-iso-to-machine-test";
- private String cloneName = vmName + "_clone";
+ private VmSpec clonedVmSpec;
+ private VmSpec sourceVmSpec;
+
+ private CleanupMode mode = CleanupMode.Full;
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setupClient() {
+ super.setupClient();
+ String sourceName = VIRTUALBOX_IMAGE_PREFIX
+ + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
+ String cloneName = VIRTUALBOX_IMAGE_PREFIX
+ + "Clone#" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName()
+ );
+
+ StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
+ .attachISO(0, 0, operatingSystemIso).attachHardDisk(
+ HardDisk.builder().diskpath(adminDisk).controllerPort(0).deviceSlot(1).autoDelete(true).build()).attachISO(1, 1,
+ guestAdditionsIso).build();
+
+ sourceVmSpec = VmSpec.builder().id(sourceName).name(sourceName).osTypeId("").memoryMB(512).cleanUpMode(
+ CleanupMode.Full).controller(ideController).forceOverwrite(true).build();
+
+ clonedVmSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(mode)
+ .forceOverwrite(true).build();
+ }
@Test
public void testCloneMachineFromAnotherMachine() throws Exception {
- VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
- ComputeServiceContext localHostContext =
- computeServiceForLocalhostAndGuest(hostId, "localhost", guestId, "localhost", new Credentials("toor", "password"));
+ try {
+ IMachine source = getSourceNode();
- IMachine master = getMasterNode(manager, localHostContext);
+ if (source.getCurrentSnapshot() != null) {
+ ISession session = manager.get().openMachineSession(source);
+ session.getConsole().deleteSnapshot(source.getCurrentSnapshot().getId());
+ session.unlockMachine();
+ }
- if (master.getCurrentSnapshot() != null) {
- ISession session = manager.openMachineSession(master);
- session.getConsole().deleteSnapshot(master.getCurrentSnapshot().getId());
- session.unlockMachine();
+ IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, clonedVmSpec,
+ IS_LINKED_CLONE).apply(source);
+ assertEquals(clone.getName(), clonedVmSpec.getVmName());
+ } finally {
+ for (VmSpec spec : ImmutableSet.of(clonedVmSpec, sourceVmSpec))
+ undoVm(spec);
}
- IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(
- manager, localHostContext, settingsFile, osTypeId, vmId,
- forceOverwrite, cloneName, hostId, snapshotName, snapshotDesc,
- controllerIDE).apply(master);
- assertEquals(clone.getNetworkAdapter(0L).getAttachmentType(), Bridged);
}
- private IMachine getMasterNode(VirtualBoxManager manager, ComputeServiceContext localHostContext) {
+ private IMachine getSourceNode() {
try {
- Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS);
- String workingDir = PropertyUtils.getWorkingDirFromProperty();
- StorageController ideController = StorageController.builder().name(controllerIDE).bus(StorageBus.IDE)
- .attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
- .attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
- .controllerPort(0).deviceSlot(1).build())
- .attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
- VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).osTypeId(osTypeId)
- .memoryMB(512)
- .cleanUpMode(CleanupMode.Full)
- .controller(ideController)
- .forceOverwrite(true).build();
- return new CreateAndInstallVm(manager, guestId, localHostContext, hostId, socketTester,
- "127.0.0.1", 8080, HEADLESS).apply(vmSpecification);
+ return context.utils().injector().getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(
+ sourceVmSpec);
} catch (IllegalStateException e) {
// already created
- return manager.getVBox().findMachine(vmName);
+ return manager.get().getVBox().findMachine(sourceVmSpec.getVmId());
}
}
}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
index 3be5c1a..b3249d1 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndInstallVmLiveTest.java
@@ -22,43 +22,34 @@
import static com.google.common.base.Predicates.equalTo;
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.transform;
-import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS;
-import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.testng.Assert.assertTrue;
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
-import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
-import org.jclouds.domain.Credentials;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
-import org.jclouds.net.IPSocket;
-import org.jclouds.predicates.InetSocketAddressConnect;
-import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.NatAdapter;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
-import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
-import org.jclouds.virtualbox.util.PropertyUtils;
-import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.StorageBus;
-import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.CaseFormat;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.google.inject.Guice;
/**
@@ -71,46 +62,32 @@
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.getInstance(Json.class));
- private String vmId = "jclouds-image-iso-1";
- private String osTypeId = "";
- private String ideControllerName = "IDE Controller";
- private String guestId = "guest";
- private String hostId = "host";
- private String vmName = "jclouds-image-virtualbox-iso-to-machine-test";
- private StorageController ideController;
private VmSpec vmSpecification;
- @BeforeGroups(groups = {"live"})
- public void setUp() throws Exception {
- identity = "toor";
- credential = "password";
-
- String workingDir = PropertyUtils.getWorkingDirFromProperty();
- HardDisk hardDisk = HardDisk.builder().diskpath(workingDir + "/testadmin.vdi").autoDelete(true)
+ @Override
+ @BeforeClass(groups = "live")
+ public void setupClient() {
+ super.setupClient();
+ String vmName = VIRTUALBOX_IMAGE_PREFIX
+ + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
+
+ HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true)
.controllerPort(0).deviceSlot(1).build();
- ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
- .attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
+ StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
+ .attachISO(0, 0, operatingSystemIso)
.attachHardDisk(hardDisk)
- .attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
- vmSpecification = VmSpec.builder().id(vmId).name(vmName).memoryMB(512).osTypeId(osTypeId)
+ .attachISO(1, 1, guestAdditionsIso).build();
+ vmSpecification = VmSpec.builder().id("jclouds-image-iso-1").name(vmName).memoryMB(512).osTypeId("")
.controller(ideController)
.forceOverwrite(true)
.cleanUpMode(CleanupMode.Full)
.natNetworkAdapter(0, NatAdapter.builder().tcpRedirectRule("127.0.0.1", 2222, "", 22).build()).build();
-
- new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(vmSpecification);
+ undoVm(vmSpecification);
}
public void testCreateImageMachineFromIso() throws Exception {
- VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
- ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(hostId, "localhost", guestId,
- "localhost", new Credentials("toor", "password"));
- Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS);
-
- IMachine imageMachine = new CreateAndInstallVm(manager, guestId, localHostContext, hostId,
- socketTester, "127.0.0.1", 8080, HEADLESS)
- .apply(vmSpecification);
+ IMachine imageMachine = context.utils().injector().getInstance(CreateAndInstallVm.class).apply(vmSpecification);
IMachineToImage iMachineToImage = new IMachineToImage(manager, map);
Image newImage = iMachineToImage.apply(imageMachine);
@@ -130,5 +107,10 @@
}
};
}
-
+ @Override
+ @AfterClass(groups = "live")
+ protected void tearDown() throws Exception {
+ undoVm(vmSpecification);
+ super.tearDown();
+ }
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
index b842ef7..9f8664d 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.testng.Assert.assertEquals;
@@ -27,9 +26,6 @@
import org.jclouds.virtualbox.domain.HardDisk;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
-import org.jclouds.virtualbox.functions.admin.UnregisterMachineIfExistsAndDeleteItsMedia;
-import org.jclouds.virtualbox.util.PropertyUtils;
-import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
@@ -39,52 +35,60 @@
/**
* @author Mattias Holmqvist
*/
+@Test(groups = "live", singleThreaded = true, testName = "CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest")
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsLiveTest extends BaseVirtualBoxClientLiveTest {
private String ideControllerName;
private CleanupMode mode;
- private StorageController ideController;
-
- @BeforeMethod
- public void setUp() {
- ideControllerName = "IDE Controller";
- mode = CleanupMode.Full;
- String workingDir = PropertyUtils.getWorkingDirFromProperty();
- ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
- .attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
- .attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi")
- .controllerPort(0).deviceSlot(1).build())
- .attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
- }
+ private StorageController ideController;
- @Test
+ @Override
+ public void setupClient() {
+ super.setupClient();
+ ideControllerName = "IDE Controller";
+ mode = CleanupMode.Full;
+ ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE).attachISO(0, 0,
+ operatingSystemIso).attachHardDisk(
+ HardDisk.builder().diskpath(adminDisk).controllerPort(0).deviceSlot(1).build()).attachISO(1, 1,
+ guestAdditionsIso).build();
+ }
+
+ @Test
public void testCreateNewMachine() throws Exception {
String vmName = "jclouds-test-create-1-node";
- VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController).cleanUpMode(mode)
- .osTypeId("Debian").forceOverwrite(true).build();
- new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
- IMachine debianNode = new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
- IMachine machine = manager.getVBox().findMachine(vmName);
- assertEquals(debianNode.getName(), machine.getName());
- new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
+ VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController)
+ .cleanUpMode(mode).osTypeId("Debian").forceOverwrite(true).build();
+ undoVm(launchSpecification);
+ try {
+ IMachine debianNode = context.utils().injector().getInstance(
+ CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(launchSpecification);
+ IMachine machine = manager.get().getVBox().findMachine(vmName);
+ assertEquals(debianNode.getName(), machine.getName());
+ } finally {
+ undoVm(launchSpecification);
+ }
}
@Test
public void testCreateNewMachineWithBadOsType() throws Exception {
String vmName = "jclouds-test-create-2-node";
- VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController).cleanUpMode(mode)
- .osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build();
- new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(launchSpecification);
+ VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).memoryMB(512).controller(ideController)
+ .cleanUpMode(mode).osTypeId("SomeWeirdUnknownOs").forceOverwrite(true).build();
+ undoVm(launchSpecification);
try {
- new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
+ context.utils().injector().getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class).apply(
+ launchSpecification);
fail();
} catch (VBoxException e) {
ErrorCode errorCode = ErrorCode.valueOf(e);
// According to the documentation VBOX_E_OBJECT_NOT_FOUND
// if osTypeId is not found.
assertEquals(errorCode, ErrorCode.VBOX_E_OBJECT_NOT_FOUND);
+ } finally {
+ undoVm(launchSpecification);
}
+
}
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java
index c2b7d2f..d285e3f 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.easymock.EasyMock.anyBoolean;
@@ -33,28 +32,35 @@
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.IVirtualBox;
+import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
+
/**
* @author Mattias Holmqvist
*/
@Test(groups = "unit", testName = "CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest")
public class CreateAndRegisterMachineFromIsoIfNotAlreadyExistsTest {
- @Test
- public void testCreateIfNotAlreadyExists() throws Exception {
+ @Test(enabled = false)
+ public void testCreateAndSetMemoryWhenNotAlreadyExists() throws Exception {
- VirtualBoxManager manager = createNiceMock(VirtualBoxManager.class);
+ VirtualBoxManager manager = createMock(VirtualBoxManager.class);
IVirtualBox vBox = createMock(IVirtualBox.class);
String vmName = "jclouds-image-my-ubuntu-image";
- VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).osTypeId("").memoryMB(1024).cleanUpMode(CleanupMode.Full).build();
+ VmSpec launchSpecification = VmSpec.builder().id(vmName).name(vmName).osTypeId("").memoryMB(1024).cleanUpMode(
+ CleanupMode.Full).build();
IMachine createdMachine = createMock(IMachine.class);
+ ISession session = createMock(ISession.class);
expect(manager.getVBox()).andReturn(vBox).anyTimes();
+ expect(vBox.composeMachineFilename(vmName, "/tmp/workingDir")).andReturn("settingsFile");
StringBuilder errorMessageBuilder = new StringBuilder();
errorMessageBuilder.append("VirtualBox error: Could not find a registered machine named ");
@@ -62,19 +68,28 @@
String errorMessage = errorMessageBuilder.toString();
VBoxException vBoxException = new VBoxException(createNiceMock(Throwable.class), errorMessage);
- vBox.findMachine(vmName);
- expectLastCall().andThrow(vBoxException);
+ expect(vBox.findMachine(vmName)).andThrow(vBoxException);
expect(vBox.createMachine(anyString(), eq(vmName), anyString(), anyString(), anyBoolean())).andReturn(
- createdMachine).anyTimes();
-
+ createdMachine).anyTimes();
vBox.registerMachine(createdMachine);
+
+ expect(vBox.findMachine(vmName)).andReturn(createdMachine).anyTimes();
+ expect(manager.getSessionObject()).andReturn(session);
+ expect(session.getMachine()).andReturn(createdMachine);
+ createdMachine.lockMachine(session, LockType.Write);
+ createdMachine.setMemorySize(1024l);
+ createdMachine.saveSettings();
+ session.unlockMachine();
+
+
+ //TODO: this mock test is not finished.
+
+ replay(manager, createdMachine, vBox, session);
- replay(manager, vBox);
+ new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Suppliers.ofInstance(manager), "/tmp/workingDir").apply(launchSpecification);
- new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
-
- verify(manager, vBox);
+ verify(manager, createdMachine, vBox, session);
}
@Test(expectedExceptions = IllegalStateException.class)
@@ -91,8 +106,9 @@
replay(manager, vBox);
- VmSpec launchSpecification = VmSpec.builder().id("").name(vmName).osTypeId("").memoryMB(1024).cleanUpMode(CleanupMode.Full).build();
- new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
+ VmSpec launchSpecification = VmSpec.builder().id("").name(vmName).osTypeId("").memoryMB(1024).cleanUpMode(
+ CleanupMode.Full).build();
+ new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Suppliers.ofInstance(manager), "/tmp/workingDir").apply(launchSpecification);
}
@Test(expectedExceptions = VBoxException.class)
@@ -112,12 +128,13 @@
replay(manager, vBox);
- VmSpec launchSpecification = VmSpec.builder().id("").name(vmName).osTypeId("").cleanUpMode(CleanupMode.Full).memoryMB(1024).build();
- new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(manager).apply(launchSpecification);
+ VmSpec launchSpecification = VmSpec.builder().id("").name(vmName).osTypeId("").cleanUpMode(CleanupMode.Full)
+ .memoryMB(1024).build();
+ new CreateAndRegisterMachineFromIsoIfNotAlreadyExists(Suppliers.ofInstance(manager), "/tmp/workingDir").apply(launchSpecification);
}
private String anyString() {
- return EasyMock.<String>anyObject();
+ return EasyMock.<String> anyObject();
}
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsLiveTest.java
index c38c5d7..0ced37c 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsLiveTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.testng.Assert.assertEquals;
@@ -30,6 +29,8 @@
import org.jclouds.virtualbox.domain.HardDisk;
import org.testng.annotations.Test;
import org.virtualbox_4_1.DeviceType;
+import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IProgress;
import org.virtualbox_4_1.VBoxException;
/**
@@ -41,9 +42,13 @@
public void testCreateMedium() throws Exception {
String path = System.getProperty("user.home") + "/jclouds-virtualbox-test/test-medium-1.vdi";
HardDisk hardDisk = HardDisk.builder().diskpath(path).controllerPort(0).deviceSlot(0).build();
- new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
- manager.getVBox().findMedium(path, DeviceType.HardDisk);
- assertFileCanBeDeleted(path);
+ IMedium iMedium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ manager.get().getVBox().findMedium(path, DeviceType.HardDisk);
+ try {
+ assertFileCanBeDeleted(path);
+ } finally {
+ deleteMediumAndBlockUntilComplete(iMedium);
+ }
}
@Test
@@ -63,10 +68,15 @@
public void testCreateSameMediumTwiceWhenUsingOverwrite() throws Exception {
String path = System.getProperty("user.home") + "/jclouds-virtualbox-test/test-medium-3.vdi";
HardDisk hardDisk = HardDisk.builder().diskpath(path).controllerPort(0).deviceSlot(0).build();
- new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
- new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
- manager.getVBox().findMedium(path, DeviceType.HardDisk);
- assertFileCanBeDeleted(path);
+ IMedium iMedium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ iMedium = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ manager.get().getVBox().findMedium(path, DeviceType.HardDisk);
+ try {
+ assertFileCanBeDeleted(path);
+ } finally {
+ deleteMediumAndBlockUntilComplete(iMedium);
+ }
+
}
private void assertFileCanBeDeleted(String path) {
@@ -74,4 +84,10 @@
boolean mediumDeleted = file.delete();
assertTrue(mediumDeleted);
}
+
+ void deleteMediumAndBlockUntilComplete(IMedium medium) {
+ final IProgress progress = medium.deleteStorage();
+ progress.waitForCompletion(-1);
+ }
+
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsTest.java
index 5952faf..685cd25 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/CreateMediumIfNotAlreadyExistsTest.java
@@ -34,11 +34,17 @@
import org.virtualbox_4_1.DeviceType;
import org.virtualbox_4_1.IMachine;
import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IMediumAttachment;
import org.virtualbox_4_1.IProgress;
+import org.virtualbox_4_1.ISession;
import org.virtualbox_4_1.IVirtualBox;
+import org.virtualbox_4_1.LockType;
import org.virtualbox_4_1.VBoxException;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+
/**
* @author Mattias Holmqvist
*/
@@ -46,14 +52,11 @@
private String adminDiskPath;
private String diskFormat;
- private String diskName;
-
@BeforeMethod
public void setUp() throws Exception {
adminDiskPath = "/Users/johndoe/jclouds-virtualbox-images/admin.vdi";
diskFormat = "vdi";
- diskName = "diskName";
}
@Test
@@ -82,7 +85,7 @@
replay(manager, machine, vBox, medium);
- new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ new CreateMediumIfNotAlreadyExists(Suppliers.ofInstance(manager), true).apply(hardDisk);
verify(machine, vBox);
@@ -108,12 +111,79 @@
replay(manager, machine, vBox, medium, newHardDisk, progress);
- IMedium newDisk = new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ IMedium newDisk = new CreateMediumIfNotAlreadyExists(Suppliers.ofInstance(manager), true).apply(hardDisk);
verify(machine, vBox, medium);
assertNotSame(newDisk, medium);
}
+ @Test
+ public void testDeleteAndCreateNewStorageWhenMediumExistsAndUsingOverwriteAndStillAttachedDetachesOldThing()
+ throws Exception {
+ HardDisk hardDisk = createTestHardDisk();
+
+ VirtualBoxManager manager = createNiceMock(VirtualBoxManager.class);
+ IMachine machine = createMock(IMachine.class);
+ IVirtualBox vBox = createMock(IVirtualBox.class);
+ IMedium medium = createMock(IMedium.class);
+
+ IMedium newHardDisk = createMock(IMedium.class);
+ IProgress progress = createNiceMock(IProgress.class);
+
+ expect(manager.getVBox()).andReturn(vBox).anyTimes();
+ expect(vBox.findMedium(adminDiskPath, DeviceType.HardDisk)).andReturn(medium);
+
+ String oldMachineId = "a1e03931-29f3-4370-ada3-9547b1009212";
+ String oldMachineName = "oldMachine";
+ IMachine oldMachine = createMock(IMachine.class);
+ IMediumAttachment oldAttachment = createMock(IMediumAttachment.class);
+ String oldAttachmentController = "oldAttachmentController";
+ int oldAttachmentDevice = 1;
+ int oldAttachmentPort = 2;
+ IMedium oldMedium = createMock(IMedium.class);
+ String oldMediumId = "oldMediumId";
+ ISession detachSession = createNiceMock(ISession.class);
+
+ StringBuilder errorBuilder = new StringBuilder();
+ errorBuilder.append("org.virtualbox_4_1.VBoxException: VirtualBox error: ");
+ errorBuilder.append("Cannot delete storage: medium '/Users/adriancole/jclouds-virtualbox-test/testadmin.vdi ");
+ errorBuilder.append("is still attached to the following 1 virtual machine(s): ");
+ errorBuilder.append(oldMachineId + " (0x80BB000C)");
+ String errorMessage = errorBuilder.toString();
+
+ VBoxException stillAttached = new VBoxException(createNiceMock(Throwable.class), errorMessage);
+ expect(medium.deleteStorage()).andThrow(stillAttached);
+
+ expect(vBox.findMachine(oldMachineId)).andReturn(oldMachine);
+ expect(oldMachine.getMediumAttachments()).andReturn(ImmutableList.of(oldAttachment));
+ expect(oldAttachment.getMedium()).andReturn(oldMedium);
+ expect(oldMedium.getId()).andReturn(oldMediumId);
+ // in this case, they are the same medium, so safe to detach
+ expect(medium.getId()).andReturn(oldMediumId);
+ expect(oldMachine.getName()).andReturn(oldMachineName);
+ expect(oldAttachment.getController()).andReturn(oldAttachmentController);
+ expect(oldAttachment.getDevice()).andReturn(oldAttachmentDevice);
+ expect(oldAttachment.getPort()).andReturn(oldAttachmentPort);
+ // TODO: is this ok that we searched by ID last time?
+ expect(vBox.findMachine(oldMachineName)).andReturn(oldMachine);
+ expect(manager.getSessionObject()).andReturn(detachSession);
+ oldMachine.lockMachine(detachSession, LockType.Write);
+ expect(detachSession.getMachine()).andReturn(oldMachine);
+ oldMachine.detachDevice(oldAttachmentController, oldAttachmentPort, oldAttachmentDevice);
+ oldMachine.saveSettings();
+
+ expect(medium.deleteStorage()).andReturn(progress);
+ expect(vBox.createHardDisk(diskFormat, adminDiskPath)).andReturn(newHardDisk);
+ expect(newHardDisk.createBaseStorage(anyLong(), anyLong())).andReturn(progress);
+
+ replay(manager, oldMachine, oldAttachment, oldMedium, detachSession, machine, vBox, medium, newHardDisk, progress);
+
+ IMedium newDisk = new CreateMediumIfNotAlreadyExists(Suppliers.ofInstance(manager), true).apply(hardDisk);
+
+ verify(machine, oldMachine, oldAttachment, detachSession, oldMedium, vBox, medium);
+ assertNotSame(newDisk, medium);
+ }
+
@Test(expectedExceptions = IllegalStateException.class)
public void testFailWhenMediumExistsAndNotUsingOverwrite() throws Exception {
HardDisk hardDisk = createTestHardDisk();
@@ -130,7 +200,7 @@
replay(manager, machine, vBox, medium, newHardDisk, progress);
- new CreateMediumIfNotAlreadyExists(manager, false).apply(hardDisk);
+ new CreateMediumIfNotAlreadyExists(Suppliers.ofInstance(manager), false).apply(hardDisk);
}
@Test(expectedExceptions = VBoxException.class)
@@ -155,7 +225,7 @@
replay(manager, machine, vBox, medium);
- new CreateMediumIfNotAlreadyExists(manager, true).apply(hardDisk);
+ new CreateMediumIfNotAlreadyExists(Suppliers.ofInstance(manager), true).apply(hardDisk);
}
private HardDisk createTestHardDisk() {
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToHardwareTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToHardwareTest.java
index 6a60144..0b0989d 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToHardwareTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToHardwareTest.java
@@ -33,6 +33,8 @@
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
+
@Test(groups = "unit")
public class IMachineToHardwareTest {
@@ -57,7 +59,7 @@
replay(vbm, vBox, vm, guestOsType);
- Hardware hardware = new IMachineToHardware(vbm).apply(vm);
+ Hardware hardware = new IMachineToHardware(Suppliers.ofInstance(vbm)).apply(vm);
assertEquals(hardware.getId(), machineId);
assertEquals(hardware.getProviderId(), machineId);
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToImageTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToImageTest.java
index 8ff77d2..af114a9 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToImageTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToImageTest.java
@@ -40,6 +40,7 @@
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
import com.google.inject.Guice;
@Test(groups = "unit")
@@ -67,7 +68,7 @@
replay(vbm, vBox, vm, guestOsType);
- IMachineToImage fn = new IMachineToImage(vbm, map);
+ IMachineToImage fn = new IMachineToImage(Suppliers.ofInstance(vbm), map);
Image image = fn.apply(vm);
@@ -98,7 +99,7 @@
replay(vbm, vBox, vm, guestOsType);
- IMachineToImage fn = new IMachineToImage(vbm, map);
+ IMachineToImage fn = new IMachineToImage(Suppliers.ofInstance(vbm), map);
Image image = fn.apply(vm);
@@ -129,7 +130,9 @@
replay(vbm, vBox, vm, guestOsType);
- Image image = new IMachineToImage(vbm, map).apply(vm);
+ IMachineToImage fn = new IMachineToImage(Suppliers.ofInstance(vbm), map);
+
+ Image image = fn.apply(vm);
assertEquals(image.getOperatingSystem().getDescription(), "SomeOtherOs 2.04");
assertEquals(image.getOperatingSystem().getVersion(), "");
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
index 62c454f..ce590ca 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToNodeMetadataTest.java
@@ -31,6 +31,7 @@
import org.virtualbox_4_1.MachineState;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
public class IMachineToNodeMetadataTest {
@@ -47,7 +48,7 @@
VirtualBox virtualBox = new VirtualBox();
IMachineToNodeMetadata parser = new IMachineToNodeMetadata();
- IMachineToHardware hwParser = new IMachineToHardware(manager);
+ IMachineToHardware hwParser = new IMachineToHardware(Suppliers.ofInstance(manager));
// hwParser.apply()
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToVmSpecTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToVmSpecTest.java
new file mode 100644
index 0000000..da62099
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/IMachineToVmSpecTest.java
@@ -0,0 +1,102 @@
+/**
+ * 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.virtualbox.functions;
+
+import static org.easymock.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.createNiceMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.testng.Assert.assertEquals;
+
+import org.jclouds.virtualbox.domain.HardDisk;
+import org.jclouds.virtualbox.domain.IsoImage;
+import org.jclouds.virtualbox.domain.StorageController;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.testng.annotations.Test;
+import org.virtualbox_4_1.DeviceType;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.IMedium;
+import org.virtualbox_4_1.IMediumAttachment;
+import org.virtualbox_4_1.IStorageController;
+import org.virtualbox_4_1.StorageBus;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.collect.Lists;
+
+@Test(groups = "unit")
+public class IMachineToVmSpecTest {
+
+ private static final String PATH_TO_DVD = "/path/to/dvd";
+ private static final String PATH_TO_HD = "/path/to/hd";
+ private static final StorageBus CONTROLLER_BUS = StorageBus.IDE;
+ private static final long MEMORY_SIZE = 512L;
+ private static final String VM_NAME = "test";
+ private static final String CONTROLLER_NAME = "IDE Controller";
+ private static final String VM_ID = "test";
+
+ @Test
+ public void testConvert() throws Exception {
+
+ VirtualBoxManager vbm = createNiceMock(VirtualBoxManager.class);
+ IStorageController iStorageController = createNiceMock(IStorageController.class);
+
+ IMediumAttachment iMediumAttachment = createNiceMock(IMediumAttachment.class);
+ IMedium hd = createNiceMock(IMedium.class);
+ IMedium dvd = createNiceMock(IMedium.class);
+
+ IMachine vm = createNiceMock(IMachine.class);
+
+ expect(vm.getStorageControllers()).andReturn(Lists.newArrayList(iStorageController)).anyTimes();
+ expect(iStorageController.getName()).andReturn(CONTROLLER_NAME).anyTimes();
+ expect(iStorageController.getBus()).andReturn(CONTROLLER_BUS).anyTimes();
+ expect(vm.getMediumAttachmentsOfController(CONTROLLER_NAME)).andReturn(Lists.newArrayList(iMediumAttachment)).anyTimes();
+ expect(iMediumAttachment.getPort()).andReturn(0).once();
+ expect(iMediumAttachment.getDevice()).andReturn(0).once();
+
+ expect(iMediumAttachment.getMedium()).andReturn(hd);
+ expect(hd.getDeviceType()).andReturn(DeviceType.HardDisk).once();
+ expect(hd.getLocation()).andReturn(PATH_TO_HD).once();
+
+ expect(iMediumAttachment.getMedium()).andReturn(dvd);
+ expect(dvd.getDeviceType()).andReturn(DeviceType.DVD).once();
+ expect(dvd.getLocation()).andReturn(PATH_TO_DVD).once();
+
+ expect(vm.getName()).andReturn(VM_NAME).anyTimes();
+ expect(vm.getId()).andReturn(VM_ID).anyTimes();
+ expect(vm.getMemorySize()).andReturn(MEMORY_SIZE).anyTimes();
+
+ replay(vbm, iStorageController, iMediumAttachment, hd, dvd, vm);
+
+ VmSpec vmSpec = new IMachineToVmSpec().apply(vm);
+
+ assertEquals(vmSpec.getVmName(), VM_NAME);
+ assertEquals(vmSpec.getVmId(), VM_ID);
+ assertEquals(vmSpec.getMemory(), MEMORY_SIZE);
+ for(StorageController controller : vmSpec.getControllers()) {
+ assertEquals(controller.getName(), CONTROLLER_NAME);
+ assertEquals(controller.getBus(), CONTROLLER_BUS);
+ for (HardDisk hardDisk : controller.getHardDisks()) {
+ assertEquals(hardDisk.getDiskPath(), PATH_TO_HD);
+ }
+ for (IsoImage iso : controller.getIsoImages()) {
+ assertEquals(iso.getSourcePath(), PATH_TO_DVD);
+ }
+ }
+ }
+}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunningTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunningTest.java
index fa1f0c9..a219759 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunningTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/LaunchMachineIfNotAlreadyRunningTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
import static org.easymock.EasyMock.expect;
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfacesLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfacesLiveTest.java
index 30c9196..09388f1 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfacesLiveTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/RetrieveActiveBridgedInterfacesLiveTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,18 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions;
-import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
import static org.jclouds.virtualbox.functions.RetrieveActiveBridgedInterfaces.retrieveBridgedInterfaceNames;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import java.util.List;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.domain.Credentials;
import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
import org.testng.annotations.Test;
@@ -38,48 +34,31 @@
*/
@Test(groups = "live", singleThreaded = true, testName = "RetrieveActiveBridgedInterfacesLiveTest")
public class RetrieveActiveBridgedInterfacesLiveTest extends BaseVirtualBoxClientLiveTest {
-
- public static final String TEST1 = "Name: eth0\n"
- + "GUID: 30687465-0000-4000-8000-00261834d0cb\n"
- + "Dhcp: Disabled\n"
- + "IPAddress: 209.x.x.x\n"
- + "NetworkMask: 255.255.255.0\n"
- + "IPV6Address: fe80:0000:0000:0000:0226:18ff:fe34:d0cb\n"
- + "IPV6NetworkMaskPrefixLength: 64\n"
- + "HardwareAddress: 00:26:18:34:d0:cb\n"
- + "MediumType: Ethernet\n"
- + "Status: Up\n"
- + "VBoxNetworkName: HostInterfaceNetworking-eth0\n"
- + "\n"
- + "Name: vbox0\n"
- + "GUID: 786f6276-0030-4000-8000-5a3ded993fed\n"
- + "Dhcp: Disabled\n"
- + "IPAddress: 192.168.56.1\n"
- + "NetworkMask: 255.255.255.0\n"
- + "IPV6Address: fe80:0000:0000:0000:0226:18ff:fe34:d0cb\n"
- + "IPV6NetworkMaskPrefixLength: 0\n"
- + "HardwareAddress: 5a:3d:ed:99:3f:ed\n"
- + "MediumType: Ethernet\n"
- + "Status: Down\n"
- + "VBoxNetworkName: HostInterfaceNetworking-vbox0\n";
-
- public static final List<String> expectedBridgedInterfaces = ImmutableList.of("eth0", "vbox0");
- private String guestId = "guest";
- private String hostId = "host";
+ public static final String TEST1 = "Name: eth0\n"
+ + "GUID: 30687465-0000-4000-8000-00261834d0cb\n" + "Dhcp: Disabled\n"
+ + "IPAddress: 209.x.x.x\n" + "NetworkMask: 255.255.255.0\n"
+ + "IPV6Address: fe80:0000:0000:0000:0226:18ff:fe34:d0cb\n" + "IPV6NetworkMaskPrefixLength: 64\n"
+ + "HardwareAddress: 00:26:18:34:d0:cb\n" + "MediumType: Ethernet\n" + "Status: Up\n"
+ + "VBoxNetworkName: HostInterfaceNetworking-eth0\n" + "\n" + "Name: vbox0\n"
+ + "GUID: 786f6276-0030-4000-8000-5a3ded993fed\n" + "Dhcp: Disabled\n"
+ + "IPAddress: 192.168.56.1\n" + "NetworkMask: 255.255.255.0\n"
+ + "IPV6Address: fe80:0000:0000:0000:0226:18ff:fe34:d0cb\n" + "IPV6NetworkMaskPrefixLength: 0\n"
+ + "HardwareAddress: 5a:3d:ed:99:3f:ed\n" + "MediumType: Ethernet\n" + "Status: Down\n"
+ + "VBoxNetworkName: HostInterfaceNetworking-vbox0\n";
+
+ public static final List<String> expectedBridgedInterfaces = ImmutableList.of("eth0", "vbox0");
@Test
public void retrieveBridgedInterfaceNamesTest() {
List<String> activeBridgedInterfaceNames = retrieveBridgedInterfaceNames(TEST1);
assertEquals(activeBridgedInterfaceNames, expectedBridgedInterfaces);
}
-
+
@Test
public void retrieveAvailableBridgedInterfaceInfoTest() {
- ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(
- hostId, "localhost", guestId, "localhost", new Credentials("toor",
- "password"));
- List<String> bridgedInterface = new RetrieveActiveBridgedInterfaces(localHostContext).apply(hostId);
+ List<String> bridgedInterface = context.utils().injector().getInstance(RetrieveActiveBridgedInterfaces.class)
+ .apply(host.get());
assertFalse(bridgedInterface.isEmpty());
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttachedTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttachedTest.java
index a03baa3..3be0490 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttachedTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/TakeSnapshotIfNotAlreadyAttachedTest.java
@@ -33,6 +33,8 @@
import org.virtualbox_4_1.IVirtualBox;
import org.virtualbox_4_1.VirtualBoxManager;
+import com.google.common.base.Suppliers;
+
/**
* @author Andrea Turli
*/
@@ -64,7 +66,7 @@
session.unlockMachine();
replay(manager, machine, vBox, session, console, progress);
- new TakeSnapshotIfNotAlreadyAttached(manager, snapshotName, snapshotDesc)
+ new TakeSnapshotIfNotAlreadyAttached(Suppliers.ofInstance(manager), snapshotName, snapshotDesc)
.apply(machine);
verify(machine);
@@ -94,7 +96,7 @@
session.unlockMachine();
replay(manager, machine, vBox, session, console, progress);
- new TakeSnapshotIfNotAlreadyAttached(manager, snapshotName, snapshotDesc)
+ new TakeSnapshotIfNotAlreadyAttached(Suppliers.ofInstance(manager), snapshotName, snapshotDesc)
.apply(machine);
verify(machine);
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunningTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunningTest.java
index bcca15e..f89d4dc 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunningTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartJettyIfNotAlreadyRunningTest.java
@@ -25,29 +25,34 @@
import static org.easymock.classextension.EasyMock.verify;
import static org.testng.Assert.assertEquals;
+import java.net.URI;
+
import org.eclipse.jetty.server.Server;
import org.testng.annotations.Test;
/**
- * @author Andrea Turli
+ * @author Andrea Turli, Adrian Cole
*/
@Test(groups = "unit", singleThreaded = true, testName = "StartJettyIfNotAlreadyRunningTest")
public class StartJettyIfNotAlreadyRunningTest {
-
- private String basebaseResource = ".";
- private int port = 8080;
-
@Test
public void testLaunchJettyServerWhenAlreadyRunningDoesntLaunchAgain() {
Server jetty = createMock(Server.class);
+
+ String preconfigurationUrl = "http://foo:8080";
+
expect(jetty.getState()).andReturn(Server.STARTED);
replay(jetty);
- assertEquals(new StartJettyIfNotAlreadyRunning(jetty, port).apply(basebaseResource), jetty);
+ StartJettyIfNotAlreadyRunning starter = new StartJettyIfNotAlreadyRunning(jetty, preconfigurationUrl);
+ starter.start();
+
+ assertEquals(starter.get(), URI.create(preconfigurationUrl));
verify(jetty);
}
+
@Test
public void testLaunchJettyServerWhenNotRunningStartsJettyOnCorrectHostPortAndBasedir() {
// TODO: all yours!
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunningTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunningTest.java
index 6328cf1..c6645ce 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunningTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/StartVBoxIfNotAlreadyRunningTest.java
@@ -19,147 +19,92 @@
package org.jclouds.virtualbox.functions.admin;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.inject.AbstractModule;
-import com.google.inject.Module;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContextFactory;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.net.IPSocket;
-import org.jclouds.ssh.ConfiguresSshClient;
-import org.jclouds.ssh.SshClient;
-import org.testng.annotations.Test;
-import org.virtualbox_4_1.VirtualBoxManager;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.runAsRoot;
import java.net.URI;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.classextension.EasyMock.*;
-import static org.testng.Assert.assertEquals;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.callables.RunScriptOnNode.Factory;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
+import org.jclouds.net.IPSocket;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.testng.annotations.Test;
+import org.virtualbox_4_1.VirtualBoxManager;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Suppliers;
@Test(groups = "unit", singleThreaded = true, testName = "StartVBoxIfNotAlreadyRunningTest")
public class StartVBoxIfNotAlreadyRunningTest {
- @Test(expectedExceptions = IllegalStateException.class)
- public void testStartVboxThrowsIllegalStateExceptionIfTheNodeIdConfiguredIsntAround() throws Exception {
-
- ComputeService compute = new ComputeServiceContextFactory().createContext("stub", "foo", "bar")
- .getComputeService();
-
- VirtualBoxManager manager = createMock(VirtualBoxManager.class);
- @SuppressWarnings("unchecked")
- Predicate<IPSocket> socketTester = createMock(Predicate.class);
- String hostId = "hostId";
- URI endpointUri = URI.create("http://localhost:18083/");
- Credentials localhostCredentials = new Credentials("toor", "password");
-
- manager.connect(endpointUri.toASCIIString(), localhostCredentials.identity, localhostCredentials.credential);
-
- replay(socketTester);
- replay(manager);
-
- new StartVBoxIfNotAlreadyRunning(compute, manager, socketTester, hostId, localhostCredentials).apply(endpointUri);
-
- }
-
+ @SuppressWarnings("unchecked")
@Test
public void testStartVboxConnectsToManagerWhenPortAlreadyListening() throws Exception {
-
- ComputeService compute = new ComputeServiceContextFactory().createContext("stub", "foo", "bar")
- .getComputeService();
-
- // TODO: possibly better to use a defined name as opposed to an id, since
- // most compute services the id is not predictable.
- NodeMetadata node = Iterables.getOnlyElement(compute.createNodesInGroup("foo", 1));
- String hostId = node.getId();
-
VirtualBoxManager manager = createMock(VirtualBoxManager.class);
- @SuppressWarnings("unchecked")
- Predicate<IPSocket> socketTester = createMock(Predicate.class);
- URI endpointUri = URI.create("http://localhost:18083/");
- Credentials localhostCredentials = new Credentials("toor", "password");
+ Factory runScriptOnNodeFactory = createMock(Factory.class);
+ RetryIfSocketNotYetOpen client = createMock(RetryIfSocketNotYetOpen.class);
+ NodeMetadata host = new NodeMetadataBuilder().id("host").state(NodeState.RUNNING).build();
+ URI provider = URI.create("http://localhost:18083/");
+ String identity = "adminstrator";
+ String credential = "12345";
- expect(socketTester.apply(new IPSocket(endpointUri.getHost(), endpointUri.getPort()))).andReturn(true);
- manager.connect(endpointUri.toASCIIString(), localhostCredentials.identity, localhostCredentials.credential);
+ expect(client.apply(new IPSocket(provider.getHost(), provider.getPort()))).andReturn(true);
- replay(socketTester);
- replay(manager);
+ manager.connect(provider.toASCIIString(), identity, credential);
- assertEquals(
- new StartVBoxIfNotAlreadyRunning(compute, manager, socketTester, hostId, localhostCredentials)
- .apply(endpointUri),
- manager);
+ replay(manager, runScriptOnNodeFactory, client);
- verify(socketTester);
- verify(manager);
- }
+ new StartVBoxIfNotAlreadyRunning((Function) Functions.constant(manager), runScriptOnNodeFactory, client,
+ Suppliers.ofInstance(host), provider, identity, credential).start();
- @ConfiguresSshClient
- static class StartingVBoxWhenNotRunningModule extends AbstractModule {
-
- @Override
- protected void configure() {
- SshClient.Factory factory = createMock(SshClient.Factory.class);
- SshClient client = createMock(SshClient.class);
- // NOTE we may want to switch to a node supplier so that we can predict
- // these values. Right now, it is node 2 since the above test made node
- // 1.
- IPSocket expectedSshSockectFor2ndCreatedNode = new IPSocket("144.175.1.2", 22);
- LoginCredentials loginCredentials = new LoginCredentials("root", "password2", null, false);
- expect(factory.create(expectedSshSockectFor2ndCreatedNode, loginCredentials)).andReturn(
- client).times(2);
-
- expect(client.getUsername()).andReturn(loginCredentials.identity).times(2);
- expect(client.getHostAddress()).andReturn(expectedSshSockectFor2ndCreatedNode.getAddress()).times(2);
-
- client.disconnect();
- client.connect();
- expect(client.exec("VBoxManage setproperty websrvauthlibrary null\n")).andReturn(new ExecResponse("", "", 0));
-
- client.disconnect();
- client.connect();
- expect(client.exec("vboxwebsrv -t 10000 -v -b\n")).andReturn(new ExecResponse("", "", 0));
-
- replay(factory);
- replay(client);
- bind(SshClient.Factory.class).toInstance(factory);
-
- }
+ verify(manager, runScriptOnNodeFactory, client);
}
+ @SuppressWarnings("unchecked")
@Test
public void testStartVboxDisablesPasswordAccessOnWebsrvauthlibraryStartsVboxwebsrvInBackgroundAndConnectsManagerWhenPortIsNotListening()
- throws Exception {
- ComputeService compute = new ComputeServiceContextFactory().createContext("stub", "foo", "bar",
- ImmutableSet.<Module> of(new StartingVBoxWhenNotRunningModule())).getComputeService();
- NodeMetadata node = Iterables.getOnlyElement(compute.createNodesInGroup("foo", 1));
- String hostId = node.getId();
-
+ throws Exception {
VirtualBoxManager manager = createMock(VirtualBoxManager.class);
- @SuppressWarnings("unchecked")
- Predicate<IPSocket> socketTester = createMock(Predicate.class);
- Credentials localhostCredentials = new Credentials("toor", "password");
- URI endpointUri = URI.create("http://localhost:18083/");
+ Factory runScriptOnNodeFactory = createMock(Factory.class);
+ RetryIfSocketNotYetOpen client = createMock(RetryIfSocketNotYetOpen.class);
+ RunScriptOnNode runScriptOnNode = createMock(RunScriptOnNode.class);
+ NodeMetadata host = new NodeMetadataBuilder().id("host").state(NodeState.RUNNING).operatingSystem(
+ OperatingSystem.builder().description("unix").build()).build();
+ URI provider = URI.create("http://localhost:18083/");
+ String identity = "adminstrator";
+ String credential = "12345";
- expect(socketTester.apply(new IPSocket(endpointUri.getHost(), endpointUri.getPort()))).andReturn(false);
+ expect(client.apply(new IPSocket(provider.getHost(), provider.getPort()))).andReturn(false);
+ expect(
+ runScriptOnNodeFactory.create(host, Statements.exec("VBoxManage setproperty websrvauthlibrary null"),
+ runAsRoot(false).wrapInInitScript(false))).andReturn(runScriptOnNode);
+ expect(runScriptOnNode.init()).andReturn(runScriptOnNode);
+ expect(runScriptOnNode.call()).andReturn(new ExecResponse("", "", 0));
+
+ expect(
+ runScriptOnNodeFactory.create(host, Statements.exec("vboxwebsrv -t 10000 -v -b"), runAsRoot(false)
+ .wrapInInitScript(false).blockOnComplete(false).nameTask("vboxwebsrv"))).andReturn(
+ runScriptOnNode);
+ expect(runScriptOnNode.init()).andReturn(runScriptOnNode);
+ expect(runScriptOnNode.call()).andReturn(new ExecResponse("", "", 0));
+
+ manager.connect(provider.toASCIIString(), identity, credential);
- manager.connect(endpointUri.toASCIIString(), localhostCredentials.identity, localhostCredentials.credential);
+ replay(manager, runScriptOnNodeFactory, runScriptOnNode, client);
+ new StartVBoxIfNotAlreadyRunning((Function) Functions.constant(manager), runScriptOnNodeFactory, client,
+ Suppliers.ofInstance(host), provider, identity, credential).start();
+ verify(manager, runScriptOnNodeFactory, runScriptOnNode, client);
- replay(socketTester);
- replay(manager);
-
- assertEquals(
- new StartVBoxIfNotAlreadyRunning(compute, manager, socketTester, hostId, localhostCredentials)
- .apply(endpointUri),
- manager);
-
- verify(socketTester);
- verify(manager);
}
-}
+}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMediaTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMediaTest.java
index fb38eab..3946717 100644
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMediaTest.java
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/functions/admin/UnregisterMachineIfExistsAndDeleteItsMediaTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.virtualbox.functions.admin;
import static org.easymock.EasyMock.expect;
@@ -33,7 +32,6 @@
import org.jclouds.virtualbox.domain.NatAdapter;
import org.jclouds.virtualbox.domain.StorageController;
import org.jclouds.virtualbox.domain.VmSpec;
-import org.jclouds.virtualbox.util.PropertyUtils;
import org.testng.annotations.Test;
import org.virtualbox_4_1.CleanupMode;
import org.virtualbox_4_1.IMachine;
@@ -61,11 +59,10 @@
List<IMedium> media = new ArrayList<IMedium>();
List<IMedium> mediums = Collections.unmodifiableList(media);
- String workingDir = PropertyUtils.getWorkingDirFromProperty();
StorageController ideController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE)
- .attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
- .attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi").controllerPort(0).deviceSlot(1).build())
- .attachISO(1, 1, workingDir + "/VBoxGuestAdditions_4.1.2.iso").build();
+ .attachISO(0, 0, "/tmp/ubuntu-11.04-server-i386.iso")
+ .attachHardDisk(HardDisk.builder().diskpath("/tmp/testadmin.vdi").controllerPort(0).deviceSlot(1).build())
+ .attachISO(1, 1, "/tmp/VBoxGuestAdditions_4.1.2.iso").build();
VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).memoryMB(512).osTypeId(osTypeId)
.controller(ideController)
.forceOverwrite(true)
@@ -83,7 +80,7 @@
replay(manager, vBox, registeredMachine, progress);
- new UnregisterMachineIfExistsAndDeleteItsMedia(manager).apply(vmSpecification);
+ new UnregisterMachineIfExistsAndDeleteItsMedia(vmSpecification).apply(registeredMachine);
}
}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IsLinkedClonesLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IsLinkedClonesLiveTest.java
new file mode 100644
index 0000000..b4a86d8
--- /dev/null
+++ b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/IsLinkedClonesLiveTest.java
@@ -0,0 +1,108 @@
+/**
+ * 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.virtualbox.predicates;
+
+import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_IMAGE_PREFIX;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
+import org.jclouds.virtualbox.domain.HardDisk;
+import org.jclouds.virtualbox.domain.StorageController;
+import org.jclouds.virtualbox.domain.VmSpec;
+import org.jclouds.virtualbox.functions.CloneAndRegisterMachineFromIMachineIfNotAlreadyExists;
+import org.jclouds.virtualbox.functions.CreateAndRegisterMachineFromIsoIfNotAlreadyExists;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.virtualbox_4_1.CleanupMode;
+import org.virtualbox_4_1.IMachine;
+import org.virtualbox_4_1.StorageBus;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ *
+ * @author Andrea Turli
+ */
+@Test(groups = "live", singleThreaded = true, testName = "IsLinkedClonesLiveTest")
+public class IsLinkedClonesLiveTest extends BaseVirtualBoxClientLiveTest {
+
+ private static final boolean IS_LINKED_CLONE = true;
+ private String vmId = "jclouds-image-iso-1";
+ private String osTypeId = "";
+ private String ideControllerName = "IDE Controller";
+ private String cloneName;
+ private String vmName;
+ private StorageController masterStorageController;
+ private VmSpec masterSpec;
+ private VmSpec cloneSpec;
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setupClient() {
+ super.setupClient();
+ vmName = VIRTUALBOX_IMAGE_PREFIX
+ + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
+
+ cloneName = VIRTUALBOX_IMAGE_PREFIX
+ + "Clone#" + CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, getClass().getSimpleName());
+
+ HardDisk hardDisk = HardDisk.builder().diskpath(adminDisk).autoDelete(true).controllerPort(0).deviceSlot(1)
+ .build();
+ masterStorageController = StorageController.builder().name(ideControllerName).bus(StorageBus.IDE).attachISO(0, 0,
+ operatingSystemIso).attachHardDisk(hardDisk).attachISO(1, 1, guestAdditionsIso).build();
+ masterSpec = VmSpec.builder().id(vmId).name(vmName).memoryMB(512).osTypeId(osTypeId).controller(
+ masterStorageController).forceOverwrite(true).cleanUpMode(CleanupMode.Full).build();
+
+ cloneSpec = VmSpec.builder().id(cloneName).name(cloneName).memoryMB(512).cleanUpMode(CleanupMode.Full)
+ .forceOverwrite(true).build();
+ }
+
+ @Test
+ public void testLinkedClone() {
+
+ IMachine master = context.utils().injector().getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class)
+ .apply(masterSpec);
+ IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec,
+ IS_LINKED_CLONE).apply(master);
+
+ assertTrue(new IsLinkedClone(manager).apply(clone));
+ }
+
+ /*
+ public void testFullClone() {
+ IMachine master = context.utils().injector().getInstance(CreateAndRegisterMachineFromIsoIfNotAlreadyExists.class)
+ .apply(masterSpec);
+ IMachine clone = new CloneAndRegisterMachineFromIMachineIfNotAlreadyExists(manager, workingDir, cloneSpec,
+ !IS_LINKED_CLONE).apply(master);
+
+ assertFalse(new IsLinkedClone(manager).apply(clone));
+ }
+ */
+
+ @BeforeMethod
+ @AfterMethod
+ void cleanUpVms() {
+ for (VmSpec spec : ImmutableSet.of(cloneSpec, masterSpec))
+ this.undoVm(spec);
+ }
+}
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java
deleted file mode 100644
index cb62918..0000000
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/predicates/SshAvailableLiveTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.jclouds.virtualbox.predicates;
-
-import static org.jclouds.virtualbox.domain.ExecutionType.HEADLESS;
-import static org.jclouds.virtualbox.experiment.TestUtils.computeServiceForLocalhostAndGuest;
-import static org.jclouds.virtualbox.util.MachineUtils.applyForMachine;
-import static org.jclouds.virtualbox.util.MachineUtils.lockSessionOnMachineAndApply;
-import static org.testng.Assert.assertTrue;
-import static org.virtualbox_4_1.LockType.Shared;
-
-import java.util.concurrent.TimeUnit;
-
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.domain.Credentials;
-import org.jclouds.net.IPSocket;
-import org.jclouds.predicates.InetSocketAddressConnect;
-import org.jclouds.predicates.RetryablePredicate;
-import org.jclouds.virtualbox.BaseVirtualBoxClientLiveTest;
-import org.jclouds.virtualbox.domain.ExecutionType;
-import org.jclouds.virtualbox.domain.HardDisk;
-import org.jclouds.virtualbox.domain.StorageController;
-import org.jclouds.virtualbox.domain.VmSpec;
-import org.jclouds.virtualbox.functions.CreateAndInstallVm;
-import org.jclouds.virtualbox.functions.LaunchMachineIfNotAlreadyRunning;
-import org.jclouds.virtualbox.util.PropertyUtils;
-import org.testng.annotations.Test;
-import org.virtualbox_4_1.IMachine;
-import org.virtualbox_4_1.IProgress;
-import org.virtualbox_4_1.ISession;
-import org.virtualbox_4_1.StorageBus;
-import org.virtualbox_4_1.VirtualBoxManager;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-
-@Test(groups = "live", singleThreaded = true, testName = "SshAvailableLiveTest")
-public class SshAvailableLiveTest extends BaseVirtualBoxClientLiveTest {
-
- private String guestId = "guest";
- private String hostId = "host";
-
- private String vmName = "jclouds-image-virtualbox-iso-to-machine-sshtest";
-
- @Test
- public void testSshDaemonIsRunning() {
- VirtualBoxManager manager = (VirtualBoxManager) context.getProviderSpecificContext().getApi();
- ComputeServiceContext localHostContext = computeServiceForLocalhostAndGuest(
- hostId, "localhost", guestId, "localhost", new Credentials("toor", "password"));
-
- getNodeWithSshDaemonRunning(manager, localHostContext);
- ensureMachineIsLaunched(vmName);
- RetryablePredicate<String> predicate = new RetryablePredicate<String>(
- new SshAvailable(localHostContext), 5, 1,
- TimeUnit.SECONDS);
- assertTrue(predicate.apply(guestId));
-
- lockSessionOnMachineAndApply(manager, Shared, vmName, new Function<ISession, Void>() {
-
- @Override
- public Void apply(ISession session) {
- IProgress powerDownProgress = session.getConsole().powerDown();
- powerDownProgress.waitForCompletion(-1);
- return null;
- }
-
- });
- }
-
- private IMachine getNodeWithSshDaemonRunning(VirtualBoxManager manager, ComputeServiceContext localHostContext) {
- try {
- Predicate<IPSocket> socketTester = new RetryablePredicate<IPSocket>(
- new InetSocketAddressConnect(), 10, 1, TimeUnit.SECONDS);
- String vmId = "jclouds-image-iso-2";
-
- String workingDir = PropertyUtils.getWorkingDirFromProperty();
- StorageController ideController = StorageController.builder().name("IDE Controller").bus(StorageBus.IDE)
- .attachISO(0, 0, workingDir + "/ubuntu-11.04-server-i386.iso")
- .attachHardDisk(HardDisk.builder().diskpath(workingDir + "/testadmin.vdi").controllerPort(0).deviceSlot(1).build()).build();
- VmSpec vmSpecification = VmSpec.builder().id(vmId).name(vmName).osTypeId("")
- .memoryMB(512)
- .controller(ideController)
- .forceOverwrite(true).build();
-
- return new CreateAndInstallVm(manager, guestId, localHostContext,
- hostId, socketTester, "127.0.0.1", 8080, HEADLESS).apply(vmSpecification);
- } catch (IllegalStateException e) {
- // already created
- return manager.getVBox().findMachine(vmName);
- }
- }
-
- private void ensureMachineIsLaunched(String vmName) {
- applyForMachine(manager, vmName, new LaunchMachineIfNotAlreadyRunning(
- manager, ExecutionType.GUI, ""));
- }
-
-}
\ No newline at end of file
diff --git a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/util/PropertyUtils.java b/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/util/PropertyUtils.java
deleted file mode 100644
index fe34719..0000000
--- a/sandbox-apis/virtualbox/src/test/java/org/jclouds/virtualbox/util/PropertyUtils.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.virtualbox.util;
-
-import static org.jclouds.virtualbox.config.VirtualBoxConstants.VIRTUALBOX_WORKINGDIR;
-
-public class PropertyUtils {
-
- public static String getWorkingDirFromProperty() {
- final String defaultWorkingDir = System.getProperty("user.home") + "/jclouds-virtualbox-test";
- return System.getProperty(VIRTUALBOX_WORKINGDIR, defaultWorkingDir);
- }
-
-}
diff --git a/sandbox-apis/virtualbox/src/test/resources/logback.xml b/sandbox-apis/virtualbox/src/test/resources/logback.xml
index d68d005..c1bb1b7 100644
--- a/sandbox-apis/virtualbox/src/test/resources/logback.xml
+++ b/sandbox-apis/virtualbox/src/test/resources/logback.xml
@@ -1,15 +1,64 @@
<?xml version="1.0"?>
<configuration scan="false">
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern>
- </encoder>
- </appender>
- <!-- turn OFF all logging (children can override) -->
- <root level="OFF">
- <appender-ref ref="STDOUT"/>
- </root>
- <logger name="jclouds.compute" level="debug"/>
- <logger name="jclouds.headers" level="debug"/>
- <logger name="jclouds.ssh" level="debug"/>
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>target/test-data/jclouds.log</file>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
+ <file>target/test-data/jclouds-wire.log</file>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
+ <file>target/test-data/jclouds-compute.log</file>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <appender name="SSHFILE" class="ch.qos.logback.core.FileAppender">
+ <file>target/test-data/jclouds-ssh.log</file>
+
+ <layout class="ch.qos.logback.classic.PatternLayout">
+ <Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
+ </layout>
+ </appender>
+
+ <root>
+ <level value="warn" />
+ </root>
+
+ <logger name="org.jclouds">
+ <level value="DEBUG" />
+ <appender-ref ref="FILE" />
+ </logger>
+
+ <logger name="jclouds.wire">
+ <level value="DEBUG" />
+ <appender-ref ref="WIREFILE" />
+ </logger>
+
+ <logger name="jclouds.headers">
+ <level value="DEBUG" />
+ <appender-ref ref="WIREFILE" />
+ </logger>
+
+ <logger name="jclouds.compute">
+ <level value="DEBUG" />
+ <appender-ref ref="COMPUTEFILE" />
+ </logger>
+
+ <logger name="jclouds.ssh">
+ <level value="DEBUG" />
+ <appender-ref ref="SSHFILE" />
+ </logger>
+
</configuration>
diff --git a/sandbox-providers/aws-elb/pom.xml b/sandbox-providers/aws-elb/pom.xml
index 8e9f11f..673d042 100644
--- a/sandbox-providers/aws-elb/pom.xml
+++ b/sandbox-providers/aws-elb/pom.xml
@@ -35,12 +35,14 @@
<properties>
<test.aws-elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.aws-elb.endpoint>
- <test.aws-elb.apiversion>2010-07-01</test.aws-elb.apiversion>
+ <test.aws-elb.api-version>2010-07-01</test.aws-elb.api-version>
+ <test.aws-elb.build-version></test.aws-elb.build-version>
<test.aws-elb.identity>${test.aws.identity}</test.aws-elb.identity>
<test.aws-elb.credential>${test.aws.credential}</test.aws-elb.credential>
<test.aws-elb.compute.provider>aws-ec2</test.aws-elb.compute.provider>
<test.aws-elb.compute.endpoint>https://ec2.us-east-1.amazonaws.com</test.aws-elb.compute.endpoint>
- <test.aws-elb.compute.apiversion>2010-06-15</test.aws-elb.compute.apiversion>
+ <test.aws-elb.compute.api-version>2010-06-15</test.aws-elb.compute.api-version>
+ <test.aws-elb.compute.build-version></test.aws-elb.compute.build-version>
<test.aws-elb.compute.identity>${test.aws.identity}</test.aws-elb.compute.identity>
<test.aws-elb.compute.credential>${test.aws.credential}</test.aws-elb.compute.credential>
<test.aws-elb.compute.image-id></test.aws-elb.compute.image-id>
@@ -119,12 +121,14 @@
<configuration>
<systemPropertyVariables>
<test.aws-elb.endpoint>${test.aws-elb.endpoint}</test.aws-elb.endpoint>
- <test.aws-elb.apiversion>${test.aws-elb.apiversion}</test.aws-elb.apiversion>
+ <test.aws-elb.api-version>${test.aws-elb.api-version}</test.aws-elb.api-version>
+ <test.aws-elb.build-version>${test.aws-elb.build-version}</test.aws-elb.build-version>
<test.aws-elb.identity>${test.aws-elb.identity}</test.aws-elb.identity>
<test.aws-elb.credential>${test.aws-elb.credential}</test.aws-elb.credential>
<test.aws-elb.compute.provider>${test.aws-elb.compute.provider}</test.aws-elb.compute.provider>
<test.aws-elb.compute.endpoint>${test.aws-elb.compute.endpoint}</test.aws-elb.compute.endpoint>
- <test.aws-elb.compute.apiversion>${test.aws-elb.compute.apiversion}</test.aws-elb.compute.apiversion>
+ <test.aws-elb.compute.build-version>${test.aws-elb.compute.build-version}</test.aws-elb.compute.build-version>
+ <test.aws-elb.compute.api-version>${test.aws-elb.compute.api-version}</test.aws-elb.compute.api-version>
<test.aws-elb.compute.identity>${test.aws-elb.compute.identity}</test.aws-elb.compute.identity>
<test.aws-elb.compute.credential>${test.aws-elb.compute.credential}</test.aws-elb.compute.credential>
<test.aws-elb.compute.image-id>${test.aws-elb.compute.image-id}</test.aws-elb.compute.image-id>
diff --git a/sandbox-providers/aws-simpledb/pom.xml b/sandbox-providers/aws-simpledb/pom.xml
index 002e722..8060295 100644
--- a/sandbox-providers/aws-simpledb/pom.xml
+++ b/sandbox-providers/aws-simpledb/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.aws-simpledb.endpoint>https://sdb.amazonaws.com</test.aws-simpledb.endpoint>
- <test.aws-simpledb.apiversion>2009-04-15</test.aws-simpledb.apiversion>
+ <test.aws-simpledb.api-version>2009-04-15</test.aws-simpledb.api-version>
+ <test.aws-simpledb.build-version></test.aws-simpledb.build-version>
<test.aws-simpledb.identity>${test.aws.identity}</test.aws-simpledb.identity>
<test.aws-simpledb.credential>${test.aws.credential}</test.aws-simpledb.credential>
</properties>
@@ -93,7 +94,8 @@
<configuration>
<systemPropertyVariables>
<test.aws-simpledb.endpoint>${test.aws-simpledb.endpoint}</test.aws-simpledb.endpoint>
- <test.aws-simpledb.apiversion>${test.aws-simpledb.apiversion}</test.aws-simpledb.apiversion>
+ <test.aws-simpledb.api-version>${test.aws-simpledb.api-version}</test.aws-simpledb.api-version>
+ <test.aws-simpledb.build-version>${test.aws-simpledb.build-version}</test.aws-simpledb.build-version>
<test.aws-simpledb.identity>${test.aws-simpledb.identity}</test.aws-simpledb.identity>
<test.aws-simpledb.credential>${test.aws-simpledb.credential}</test.aws-simpledb.credential>
</systemPropertyVariables>
diff --git a/sandbox-providers/azurequeue/pom.xml b/sandbox-providers/azurequeue/pom.xml
index 48c289e..195da18 100644
--- a/sandbox-providers/azurequeue/pom.xml
+++ b/sandbox-providers/azurequeue/pom.xml
@@ -35,7 +35,8 @@
<properties>
<test.azurequeue.endpoint>https://{identity}.queue.core.windows.net</test.azurequeue.endpoint>
- <test.azurequeue.apiversion>2009-09-19</test.azurequeue.apiversion>
+ <test.azurequeue.api-version>2009-09-19</test.azurequeue.api-version>
+ <test.azurequeue.build-version></test.azurequeue.build-version>
<test.azurequeue.identity>${test.azure.identity}</test.azurequeue.identity>
<test.azurequeue.credential>${test.azure.credential}</test.azurequeue.credential>
</properties>
@@ -86,7 +87,8 @@
<configuration>
<systemPropertyVariables>
<test.azurequeue.endpoint>${test.azurequeue.endpoint}</test.azurequeue.endpoint>
- <test.azurequeue.apiversion>${test.azurequeue.apiversion}</test.azurequeue.apiversion>
+ <test.azurequeue.api-version>${test.azurequeue.api-version}</test.azurequeue.api-version>
+ <test.azurequeue.build-version>${test.azurequeue.build-version}</test.azurequeue.build-version>
<test.azurequeue.identity>${test.azurequeue.identity}</test.azurequeue.identity>
<test.azurequeue.credential>${test.azurequeue.credential}</test.azurequeue.credential>
</systemPropertyVariables>
diff --git a/sandbox-providers/azurequeue/src/test/java/org/jclouds/azurequeue/AzureQueueClientLiveTest.java b/sandbox-providers/azurequeue/src/test/java/org/jclouds/azurequeue/AzureQueueClientLiveTest.java
index 49b0e94..054dc02 100644
--- a/sandbox-providers/azurequeue/src/test/java/org/jclouds/azurequeue/AzureQueueClientLiveTest.java
+++ b/sandbox-providers/azurequeue/src/test/java/org/jclouds/azurequeue/AzureQueueClientLiveTest.java
@@ -60,15 +60,15 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
- apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
- + ".apiversion");
+ apiVersion = checkNotNull(System.getProperty("test." + provider + ".api-version"), "test." + provider
+ + ".api-version");
}
protected Properties setupProperties() {
@@ -78,7 +78,7 @@
overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential);
overrides.setProperty(provider + ".endpoint", endpoint);
- overrides.setProperty(provider + ".apiversion", apiversion);
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-providers/boxdotnet/pom.xml b/sandbox-providers/boxdotnet/pom.xml
index 8e87e04..e36166e 100644
--- a/sandbox-providers/boxdotnet/pom.xml
+++ b/sandbox-providers/boxdotnet/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.boxdotnet.endpoint>https://www.box.net/api/1.0/rest</test.boxdotnet.endpoint>
- <test.boxdotnet.apiversion>1.0</test.boxdotnet.apiversion>
+ <test.boxdotnet.api-version>1.0</test.boxdotnet.api-version>
+ <test.boxdotnet.build-version></test.boxdotnet.build-version>
<test.boxdotnet.identity>FIXME</test.boxdotnet.identity>
<test.boxdotnet.credential>FIXME</test.boxdotnet.credential>
</properties>
@@ -97,7 +98,8 @@
<configuration>
<systemPropertyVariables>
<test.boxdotnet.endpoint>${test.boxdotnet.endpoint}</test.boxdotnet.endpoint>
- <test.boxdotnet.apiversion>${test.boxdotnet.apiversion}</test.boxdotnet.apiversion>
+ <test.boxdotnet.api-version>${test.boxdotnet.api-version}</test.boxdotnet.api-version>
+ <test.boxdotnet.build-version>${test.boxdotnet.build-version}</test.boxdotnet.build-version>
<test.boxdotnet.identity>${test.boxdotnet.identity}</test.boxdotnet.identity>
<test.boxdotnet.credential>${test.boxdotnet.credential}</test.boxdotnet.credential>
</systemPropertyVariables>
diff --git a/sandbox-providers/dunkel-vcd/pom.xml b/sandbox-providers/dunkel-vcd/pom.xml
index 7c25bc9..71d887b 100644
--- a/sandbox-providers/dunkel-vcd/pom.xml
+++ b/sandbox-providers/dunkel-vcd/pom.xml
@@ -34,7 +34,8 @@
<properties>
<test.dunkel-vcd.endpoint>https://vcd.dunkel.de/api</test.dunkel-vcd.endpoint>
- <test.dunkel-vcd.apiversion>1.0</test.dunkel-vcd.apiversion>
+ <test.dunkel-vcd.api-version>1.0</test.dunkel-vcd.api-version>
+ <test.dunkel-vcd.build-version></test.dunkel-vcd.build-version>
<test.dunkel-vcd.identity>FIXME_IDENTITY</test.dunkel-vcd.identity>
<test.dunkel-vcd.credential>FIXME_CREDENTIAL</test.dunkel-vcd.credential>
<test.dunkel-vcd.image-id></test.dunkel-vcd.image-id>
@@ -99,7 +100,8 @@
<configuration>
<systemPropertyVariables>
<test.dunkel-vcd.endpoint>${test.dunkel-vcd.endpoint}</test.dunkel-vcd.endpoint>
- <test.dunkel-vcd.apiversion>${test.dunkel-vcd.apiversion}</test.dunkel-vcd.apiversion>
+ <test.dunkel-vcd.api-version>${test.dunkel-vcd.api-version}</test.dunkel-vcd.api-version>
+ <test.dunkel-vcd.build-version>${test.dunkel-vcd.build-version}</test.dunkel-vcd.build-version>
<test.dunkel-vcd.identity>${test.dunkel-vcd.identity}</test.dunkel-vcd.identity>
<test.dunkel-vcd.credential>${test.dunkel-vcd.credential}</test.dunkel-vcd.credential>
<test.dunkel-vcd.image-id>${test.dunkel-vcd.image-id}</test.dunkel-vcd.image-id>
diff --git a/sandbox-providers/glesys/pom.xml b/sandbox-providers/glesys/pom.xml
index 76873f5..3a03d0d 100644
--- a/sandbox-providers/glesys/pom.xml
+++ b/sandbox-providers/glesys/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.glesys.endpoint>https://api.glesys.com</test.glesys.endpoint>
- <test.glesys.apiversion>1</test.glesys.apiversion>
+ <test.glesys.api-version>1</test.glesys.api-version>
+ <test.glesys.build-version></test.glesys.build-version>
<test.glesys.identity>FIXME</test.glesys.identity>
<test.glesys.credential>FIXME</test.glesys.credential>
<test.glesys.image-id></test.glesys.image-id>
@@ -107,7 +108,8 @@
<configuration>
<systemPropertyVariables>
<test.glesys.endpoint>${test.glesys.endpoint}</test.glesys.endpoint>
- <test.glesys.apiversion>${test.glesys.apiversion}</test.glesys.apiversion>
+ <test.glesys.api-version>${test.glesys.api-version}</test.glesys.api-version>
+ <test.glesys.build-version>${test.glesys.build-version}</test.glesys.build-version>
<test.glesys.identity>${test.glesys.identity}</test.glesys.identity>
<test.glesys.credential>${test.glesys.credential}</test.glesys.credential>
<test.glesys.image-id>${test.glesys.image-id}</test.glesys.image-id>
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSAsyncClient.java
index 913b9fa..2249c4d 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSAsyncClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSAsyncClient.java
@@ -18,10 +18,7 @@
*/
package org.jclouds.glesys;
-import org.jclouds.glesys.features.ArchiveAsyncClient;
-import org.jclouds.glesys.features.DomainAsyncClient;
-import org.jclouds.glesys.features.IpAsyncClient;
-import org.jclouds.glesys.features.ServerAsyncClient;
+import org.jclouds.glesys.features.*;
import org.jclouds.rest.annotations.Delegate;
/**
@@ -58,4 +55,10 @@
@Delegate
DomainAsyncClient getDomainClient();
+ /**
+ * Provides asynchronous access to E-Mail features.
+ */
+ @Delegate
+ EmailAsyncClient getEmailClient();
+
}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSClient.java
index 91b9a6d..65e0d61 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSClient.java
@@ -19,10 +19,7 @@
package org.jclouds.glesys;
import org.jclouds.concurrent.Timeout;
-import org.jclouds.glesys.features.ArchiveClient;
-import org.jclouds.glesys.features.DomainClient;
-import org.jclouds.glesys.features.IpClient;
-import org.jclouds.glesys.features.ServerClient;
+import org.jclouds.glesys.features.*;
import org.jclouds.rest.annotations.Delegate;
import java.util.concurrent.TimeUnit;
@@ -60,5 +57,12 @@
* Provides synchronous access to DNS features.
*/
@Delegate
- DomainClient getDomainClient();
+ DomainClient getDomainClient();
+
+ /**
+ * Provides synchronous access to E-Mail features.
+ */
+ @Delegate
+ EmailClient getEmailClient();
+
}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSParserModule.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSParserModule.java
index a979df0..1818569 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSParserModule.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSParserModule.java
@@ -18,19 +18,20 @@
*/
package org.jclouds.glesys.config;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import javax.inject.Singleton;
+
+import org.jclouds.glesys.domain.ServerState;
+import org.jclouds.glesys.domain.ServerUptime;
+import org.jclouds.glesys.functions.internal.GleSYSTypeAdapters;
+import org.jclouds.glesys.functions.internal.GlesysDateAdapter;
+import org.jclouds.json.config.GsonModule.DateAdapter;
+
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
-import org.jclouds.glesys.domain.ServerState;
-import org.jclouds.glesys.domain.ServerUptime;
-import org.jclouds.glesys.functions.internal.CustomDeserializers;
-import org.jclouds.glesys.functions.internal.GlesysDateAdapter;
-import org.jclouds.json.config.GsonModule;
-import org.jclouds.json.config.GsonModule.DateAdapter;
-
-import javax.inject.Singleton;
-import java.lang.reflect.Type;
-import java.util.Map;
/**
* @author Adrian Cole
@@ -40,10 +41,8 @@
@Provides
@Singleton
public Map<Type, Object> provideCustomAdapterBindings() {
- return ImmutableMap.<Type, Object>of(
- ServerState.class, new CustomDeserializers.ServerStateAdapter(),
- ServerUptime.class, new CustomDeserializers.ServerUptimeAdaptor()
- );
+ return ImmutableMap.<Type, Object> of(ServerState.class, new GleSYSTypeAdapters.ServerStateAdapter(),
+ ServerUptime.class, new GleSYSTypeAdapters.ServerUptimeAdapter());
}
@Override
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSRestClientModule.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSRestClientModule.java
index e9a5879..e9d9236 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSRestClientModule.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/config/GleSYSRestClientModule.java
@@ -50,6 +50,7 @@
.put(IpClient.class, IpAsyncClient.class)//
.put(ArchiveClient.class, ArchiveAsyncClient.class)//
.put(DomainClient.class, DomainAsyncClient.class)//
+ .put(EmailClient.class, EmailAsyncClient.class)//
.build();
public GleSYSRestClientModule() {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Archive.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Archive.java
index 4f974b2..1d87820 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Archive.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Archive.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.domain;
import com.google.common.base.Objects;
@@ -7,7 +25,7 @@
* Information about an archive
*
* @author Adam Lowe
- * @see <a href= "https://customer.glesys.com/api.php?a=doc#archive_details" />
+ * @see <a href= "https://customer.glesys.com/api.php?a=doc#archive_list" />
*/
public class Archive implements Comparable<Archive> {
public static Builder builder() {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveAllowedArguments.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveAllowedArguments.java
index e01940c..2def35f 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveAllowedArguments.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveAllowedArguments.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.domain;
import com.google.common.base.Joiner;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveDetails.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveDetails.java
index 30b1503..c3530a7 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveDetails.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ArchiveDetails.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.domain;
/**
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Domain.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Domain.java
index 1b77fee..bdee0df 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Domain.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Domain.java
@@ -27,6 +27,7 @@
* Domain data for a Glesys account.
*
* @author Adam Lowe
+ * @see <a href= "https://customer.glesys.com/api.php?a=doc#domain_list" />
*/
public class Domain implements Comparable<Domain> {
public static Builder builder() {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/DomainRecord.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/DomainRecord.java
index 4ee0422..86b4fe6 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/DomainRecord.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/DomainRecord.java
@@ -24,6 +24,7 @@
* DNS record data.
*
* @author Adam Lowe
+ * @see <a href= "https://customer.glesys.com/api.php?a=doc#domain_list_records" />
*/
public class DomainRecord implements Comparable<DomainRecord> {
public static Builder builder() {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Email.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Email.java
new file mode 100644
index 0000000..3846c4e
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/Email.java
@@ -0,0 +1,213 @@
+/**
+ * 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.glesys.domain;
+
+import com.google.common.base.Objects;
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Date;
+
+/**
+ * Detailed information on an Email Account
+ *
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_list" />
+ */
+public class Email implements Comparable<Email> {
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String account;
+ private String quota;
+ private String usedQuota;
+ private int antispamLevel;
+ private boolean antiVirus;
+ private boolean autoRespond;
+ private String autoRespondMessage;
+ private boolean autoRespondSaveEmail;
+ private Date created;
+ private Date modified;
+
+ public Builder account(String account) {
+ this.account = account;
+ return this;
+ }
+
+ public Builder quota(String quota) {
+ this.quota = quota;
+ return this;
+ }
+
+ public Builder usedQuota(String usedQuota) {
+ this.usedQuota = usedQuota;
+ return this;
+ }
+
+ public Builder antispamLevel(int antispamLevel) {
+ this.antispamLevel = antispamLevel;
+ return this;
+ }
+
+ public Builder antiVirus(boolean antiVirus) {
+ this.antiVirus = antiVirus;
+ return this;
+ }
+
+ public Builder autoRespond(boolean autoRespond) {
+ this.autoRespond = autoRespond;
+ return this;
+ }
+
+ public Builder autoRespondMessage(String autoRespondMessage) {
+ this.autoRespondMessage = autoRespondMessage;
+ return this;
+ }
+
+ public Builder autoRespondSaveEmail(boolean autoRespondSaveEmail) {
+ this.autoRespondSaveEmail = autoRespondSaveEmail;
+ return this;
+ }
+
+ public Builder created(Date created) {
+ this.created = created;
+ return this;
+ }
+
+ public Builder modified(Date modified) {
+ this.modified = modified;
+ return this;
+ }
+
+ public Email build() {
+ return new Email(account, quota, usedQuota, antispamLevel, antiVirus, autoRespond, autoRespondMessage,
+ autoRespondSaveEmail, created, modified);
+ }
+
+ public Builder fromEmail(Email in) {
+ return account(in.getAccount()).quota(in.getQuota()).usedQuota(in.getUsedQuota()).antispamLevel(in.getAntispamLevel()).
+ antiVirus(in.getAntiVirus()).autoRespond(in.getAutoRespond()).autoRespondMessage(in.getAutoRespondMessage()).
+ autoRespondSaveEmail(in.getAutoRespondSaveEmail()).created(in.getCreated()).modified(in.getModified());
+ }
+ }
+
+ @SerializedName("emailaccount")
+ private final String account;
+ private final String quota;
+ @SerializedName("usedquota")
+ private final String usedQuota;
+ @SerializedName("antispamlevel")
+ private final int antispamLevel;
+ @SerializedName("antivirus")
+ private final boolean antiVirus;
+ @SerializedName("autorespond")
+ private final boolean autoRespond;
+ @SerializedName("autorespondmessage")
+ private final String autoRespondMessage;
+ @SerializedName("autorespondsaveemail")
+ private final boolean autoRespondSaveEmail;
+ private final Date created;
+ private final Date modified;
+
+ public Email(String account, String quota, String usedQuota, int antispamLevel, boolean antiVirus, boolean autoRespond, String autoRespondMessage, boolean autoRespondSaveEmail, Date created, Date modified) {
+ this.account = account;
+ this.quota = quota;
+ this.usedQuota = usedQuota;
+ this.antispamLevel = antispamLevel;
+ this.antiVirus = antiVirus;
+ this.autoRespond = autoRespond;
+ this.autoRespondMessage = autoRespondMessage;
+ this.autoRespondSaveEmail = autoRespondSaveEmail;
+ this.created = created;
+ this.modified = modified;
+ }
+
+ public String getAccount() {
+ return account;
+ }
+
+ public String getQuota() {
+ return quota;
+ }
+
+ public String getUsedQuota() {
+ return usedQuota;
+ }
+
+ public int getAntispamLevel() {
+ return antispamLevel;
+ }
+
+ public boolean getAntiVirus() {
+ return antiVirus;
+ }
+
+ public boolean getAutoRespond() {
+ return autoRespond;
+ }
+
+ public String getAutoRespondMessage() {
+ return autoRespondMessage;
+ }
+
+ public boolean getAutoRespondSaveEmail() {
+ return autoRespondSaveEmail;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public Date getModified() {
+ return modified;
+ }
+
+ @Override
+ public int compareTo(Email other) {
+ return account.compareTo(other.getAccount());
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object instanceof Email) {
+ Email other = (Email) object;
+ return Objects.equal(account, other.account);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(account);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("account=%s, quota=%s, usedquota=%s, antispamLevel=%d, " +
+ "antiVirus=%b, autoRespond=%b, autoRespondMessage=%s, autoRespondSaveEmail=%b, " +
+ "created=%s, modified=%s", account, quota, usedQuota, antispamLevel, antiVirus, autoRespond, autoRespondMessage,
+ autoRespondSaveEmail, created.toString(), modified.toString());
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverview.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverview.java
new file mode 100644
index 0000000..708dcc1
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverview.java
@@ -0,0 +1,104 @@
+/**
+ * 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.glesys.domain;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
+/**
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_overview" />
+ */
+public class EmailOverview {
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EmailOverviewSummary summary;
+ private Set<EmailOverviewDomain> domains;
+
+ public Builder summary(EmailOverviewSummary summary) {
+ this.summary = summary;
+ return this;
+ }
+
+ public Builder domains(Set<EmailOverviewDomain> domains) {
+ this.domains = domains;
+ return this;
+ }
+
+ public Builder domains(EmailOverviewDomain... domains) {
+ return domains(ImmutableSet.copyOf(domains));
+ }
+
+ public EmailOverview build() {
+ return new EmailOverview(summary, domains);
+ }
+
+ public Builder fromEmailOverview(EmailOverview in) {
+ return summary(in.getSummary()).domains(in.getDomains());
+ }
+ }
+
+ private EmailOverviewSummary summary;
+ private Set<EmailOverviewDomain> domains;
+
+ public EmailOverview(EmailOverviewSummary summary, Set<EmailOverviewDomain> domains) {
+ this.summary = summary;
+ this.domains = domains;
+ }
+
+ public EmailOverviewSummary getSummary() {
+ return summary;
+ }
+
+ public Set<EmailOverviewDomain> getDomains() {
+ return domains == null ? ImmutableSet.<EmailOverviewDomain>of() : domains;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(summary, domains);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof EmailOverview) {
+ EmailOverview other = (EmailOverview) object;
+ return Objects.equal(summary, other.summary)
+ && Objects.equal(domains, other.domains);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ Joiner commaJoiner = Joiner.on(", ");
+ return String.format("summary=%s, domains=[%s]", summary, commaJoiner.join(getDomains()));
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewDomain.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewDomain.java
new file mode 100644
index 0000000..0836645
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewDomain.java
@@ -0,0 +1,106 @@
+/**
+ * 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.glesys.domain;
+
+import com.google.common.base.Objects;
+
+/**
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_overview" />
+ */
+public class EmailOverviewDomain {
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String domain;
+ private int accounts;
+ private int aliases;
+
+ public Builder domain(String domain) {
+ this.domain = domain;
+ return this;
+ }
+
+ public Builder accounts(int accounts) {
+ this.accounts = accounts;
+ return this;
+ }
+
+ public Builder aliases(int aliases) {
+ this.aliases = aliases;
+ return this;
+ }
+
+ public EmailOverviewDomain build() {
+ return new EmailOverviewDomain(domain, accounts, aliases);
+ }
+
+ public Builder fromEmailOverview(EmailOverviewDomain in) {
+ return domain(domain).accounts(in.getAccounts()).aliases(in.getAliases());
+ }
+ }
+
+ private final String domain;
+ private final int accounts;
+ private final int aliases;
+
+ public EmailOverviewDomain(String domain, int accounts, int aliases) {
+ this.domain = domain;
+ this.accounts = accounts;
+ this.aliases = aliases;
+ }
+
+ public String getDomain() {
+ return domain;
+ }
+
+ public int getAccounts() {
+ return accounts;
+ }
+
+ public int getAliases() {
+ return aliases;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(domain);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof EmailOverviewDomain) {
+ EmailOverviewDomain other = (EmailOverviewDomain) object;
+ return Objects.equal(domain, other.domain);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("domain=%s, accounts=%d, aliases=%d", domain, accounts, aliases);
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewSummary.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewSummary.java
new file mode 100644
index 0000000..06bf114
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/EmailOverviewSummary.java
@@ -0,0 +1,124 @@
+/**
+ * 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.glesys.domain;
+
+import com.google.common.base.Objects;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_overview" />
+ */
+public class EmailOverviewSummary {
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private int accounts;
+ private int maxAccounts;
+ private int aliases;
+ private int maxAliases;
+
+ public Builder accounts(int accounts) {
+ this.accounts = accounts;
+ return this;
+ }
+
+ public Builder maxAccounts(int maxAccounts) {
+ this.maxAccounts = maxAccounts;
+ return this;
+ }
+
+ public Builder aliases(int aliases) {
+ this.aliases = aliases;
+ return this;
+ }
+
+ public Builder maxAliases(int maxAliases) {
+ this.maxAliases = maxAliases;
+ return this;
+ }
+
+ public EmailOverviewSummary build() {
+ return new EmailOverviewSummary(accounts, maxAccounts, aliases, maxAliases);
+ }
+
+ public Builder fromEmailOverview(EmailOverviewSummary in) {
+ return accounts(in.getAccounts()).maxAccounts(in.getMaxAccounts()).aliases(in.getAliases()).maxAliases(in.getMaxAliases());
+ }
+ }
+
+ private final int accounts;
+ @SerializedName("maxaccounts")
+ private final int maxAccounts;
+ private final int aliases;
+ @SerializedName("maxaliases")
+ private final int maxAliases;
+
+ public EmailOverviewSummary(int accounts, int maxAccounts, int aliases, int maxAliases) {
+ this.accounts = accounts;
+ this.maxAccounts = maxAccounts;
+ this.aliases = aliases;
+ this.maxAliases = maxAliases;
+ }
+
+ public int getAccounts() {
+ return accounts;
+ }
+
+ public int getMaxAccounts() {
+ return maxAccounts;
+ }
+
+ public int getAliases() {
+ return aliases;
+ }
+
+ public int getMaxAliases() {
+ return maxAliases;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(accounts, maxAccounts, aliases, maxAliases);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object == this) {
+ return true;
+ }
+ if (object instanceof EmailOverviewSummary) {
+ EmailOverviewSummary other = (EmailOverviewSummary) object;
+ return Objects.equal(accounts, other.accounts)
+ && Objects.equal(maxAccounts, other.maxAccounts)
+ && Objects.equal(aliases, other.aliases)
+ && Objects.equal(maxAliases, other.maxAliases);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("accounts=%d, maxAccounts=%d, aliases=%d, maxAliases=%d", accounts, maxAccounts, aliases, maxAliases);
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java
index 1e4d16f..6774568 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java
@@ -26,7 +26,7 @@
import java.util.List;
/**
- * Represents detailed information about an available IP address.
+ * Represents detailed information about an IP address.
*/
public class IpDetails {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerConsole.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerConsole.java
index 97a8692..bf15950 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerConsole.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerConsole.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.domain;
import com.google.common.base.Objects;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreated.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreated.java
index 3117f8f..07aa87b 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreated.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreated.java
@@ -1,21 +1,39 @@
+/**
+ * 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.glesys.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
+import org.jclouds.javax.annotation.Nullable;
+
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.gson.annotations.SerializedName;
-import org.jclouds.javax.annotation.Nullable;
/**
* Connection information to connect to a server with VNC.
*
* @author Adam Lowe
- * @see <a href="https://customer.glesys.com/api.php?a=doc#server_console" />
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#server_create" />
*/
public class ServerCreated {
public static Builder builder() {
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreatedIp.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreatedIp.java
index f8c2101..464355f 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreatedIp.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerCreatedIp.java
@@ -38,11 +38,19 @@
protected int version;
protected double cost;
- public Builder version(int version) {
+ protected Builder version(int version) {
this.version = version;
return this;
}
+ public Builder version4() {
+ return version(4);
+ }
+
+ public Builder version6() {
+ return version(6);
+ }
+
public Builder ip(String ip) {
this.ip = ip;
return this;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerDetails.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerDetails.java
index 1261642..e8347bf 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerDetails.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerDetails.java
@@ -20,7 +20,6 @@
import static com.google.common.base.Preconditions.checkNotNull;
-import com.google.common.base.Objects;
import com.google.gson.annotations.SerializedName;
/**
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerLimit.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerLimit.java
index b0faaa0..3a3a60b 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerLimit.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerLimit.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.domain;
import com.google.common.base.Objects;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerTemplate.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerTemplate.java
index 3f923ff..4115bb4 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerTemplate.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/ServerTemplate.java
@@ -1,6 +1,25 @@
+/**
+ * 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.glesys.domain;
import com.google.common.base.Objects;
+import com.google.common.collect.Ordering;
import com.google.gson.annotations.SerializedName;
/**
@@ -9,7 +28,7 @@
* @author Adam Lowe
* @see <a href= "https://customer.glesys.com/api.php?a=doc#server_templates" />
*/
-public class ServerTemplate {
+public class ServerTemplate implements Comparable<ServerTemplate>{
public static Builder builder() {
return new Builder();
@@ -131,4 +150,9 @@
return String.format("[name=%s, min_disk_size=%d, min_mem_size=%d, os=%s, platform=%s]",
name, minDiskSize, minMemSize, os, platform);
}
+
+ @Override
+ public int compareTo(ServerTemplate arg0) {
+ return Ordering.usingToString().compare(this, arg0);
+ }
}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveAsyncClient.java
index 2576721..4098ebe 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveAsyncClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveAsyncClient.java
@@ -55,14 +55,14 @@
ListenableFuture<Set<Archive>> listArchives();
/**
- * @see ArchiveClient#archiveDetails
+ * @see ArchiveClient#getArchiveDetails
*/
@POST
@Path("/archive/details/format/json")
@SelectJson("details")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
- ListenableFuture<ArchiveDetails> archiveDetails(@FormParam("username") String username);
+ ListenableFuture<ArchiveDetails> getArchiveDetails(@FormParam("username") String username);
/**
* @see ArchiveClient#createArchive
@@ -84,7 +84,7 @@
*/
@POST
@Path("/archive/resize/format/json")
- ListenableFuture<Void> resizeArchive(@FormParam("username") String username, @FormParam("size")int size);
+ ListenableFuture<Void> resizeArchive(@FormParam("username") String username, @FormParam("size") int size);
/**
* @see ArchiveClient#changeArchivePassword
*/
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveClient.java
index 039fb52..5180763 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ArchiveClient.java
@@ -48,7 +48,7 @@
* @param username the username associated with the archive
* @return the archive information or null if not found
*/
- ArchiveDetails archiveDetails(String username);
+ ArchiveDetails getArchiveDetails(String username);
/**
* Create a new backup volume.
@@ -73,7 +73,7 @@
* Then delete the old volume.
*
* @param username the username associated with the archive
- * @param size the new size required in GB
+ * @param size the new size required, see #getArchiveAllowedArguments for valid values
*/
void resizeArchive(String username, int size);
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailAsyncClient.java
new file mode 100644
index 0000000..7d88a81
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailAsyncClient.java
@@ -0,0 +1,107 @@
+/**
+ * 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.glesys.features;
+
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.glesys.domain.Email;
+import org.jclouds.glesys.domain.EmailOverview;
+import org.jclouds.glesys.options.EmailCreateOptions;
+import org.jclouds.glesys.options.EmailEditOptions;
+import org.jclouds.http.filters.BasicAuthentication;
+import org.jclouds.rest.annotations.ExceptionParser;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Provides asynchronous access to E-Mail data via the Glesys REST API.
+ * <p/>
+ *
+ * @author Adam Lowe
+ * @see org.jclouds.glesys.features.EmailClient
+ * @see <a href="https://customer.glesys.com/api.php" />
+ */
+@RequestFilters(BasicAuthentication.class)
+public interface EmailAsyncClient {
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#emailOverview
+ */
+ @POST
+ @Path("/email/overview/format/json")
+ @SelectJson("response")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ ListenableFuture<EmailOverview> getEmailOverview();
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#listAccounts
+ */
+ @POST
+ @Path("/email/list/format/json")
+ @SelectJson("emailaccounts")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ ListenableFuture<Set<Email>> listAccounts(@FormParam("domain") String domain);
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#createAccount
+ */
+ @POST
+ @Path("/email/createaccount/format/json")
+ ListenableFuture<Void> createAccount(@FormParam("emailaccount") String accountAddress, @FormParam("password") String password, EmailCreateOptions... options);
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#createAlias
+ */
+ @POST
+ @Path("/email/createalias/format/json")
+ ListenableFuture<Void> createAlias(@FormParam("emailalias") String aliasAddress, @FormParam("goto") String toEmailAddress);
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#editAccount
+ */
+ @POST
+ @Path("/email/editaccount/format/json")
+ ListenableFuture<Void> editAccount(@FormParam("emailaccount") String accountAddress, EmailEditOptions... options);
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#editAlias
+ */
+ @POST
+ @Path("/email/editalias/format/json")
+ ListenableFuture<Void> editAlias(@FormParam("emailalias") String aliasAddress, @FormParam("goto") String toEmailAddress);
+
+ /**
+ * @see org.jclouds.glesys.features.EmailClient#delete
+ */
+ @POST
+ @Path("/email/delete/format/json")
+ ListenableFuture<Void> delete(@FormParam("email") String accountAddress);
+
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailClient.java
new file mode 100644
index 0000000..b2304e4
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/EmailClient.java
@@ -0,0 +1,64 @@
+/**
+ * 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.glesys.features;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.concurrent.Timeout;
+import org.jclouds.glesys.domain.Email;
+import org.jclouds.glesys.domain.EmailOverview;
+import org.jclouds.glesys.options.EmailCreateOptions;
+import org.jclouds.glesys.options.EmailEditOptions;
+
+/**
+ * Provides synchronous access to E-Mail requests.
+ * <p/>
+ *
+ * @author Adam Lowe
+ * @see org.jclouds.glesys.features.DomainAsyncClient
+ * @see <a href="https://customer.glesys.com/api.php" />
+ */
+@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
+public interface EmailClient {
+
+ /**
+ * Get a summary of e-mail accounts associated with this Glesys account
+ *
+ * @return the relevant summary data
+ */
+ EmailOverview getEmailOverview();
+
+ /**
+ *
+ * @return
+ */
+ Set<Email> listAccounts(String domain);
+
+ void createAccount(String accountAddress, String password, EmailCreateOptions... options);
+
+ void createAlias(String aliasAddress, String toEmailAddress);
+
+ void editAccount(String accountAddress, EmailEditOptions... options);
+
+ void editAlias(String aliasAddress, String toEmailAddress);
+
+ void delete(String accountAddress);
+
+}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java
index 6f67d23..ab8f2c3 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java
@@ -25,11 +25,9 @@
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
+import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Set;
@@ -37,7 +35,8 @@
* Provides asynchronous access to IP Addresses via their REST API.
* <p/>
*
- * @author Adrian Cole
+ * @author Adrian Cole, Mattias Holmqvist
+ *
* @see ServerClient
* @see <a href="https://customer.glesys.com/api.php" />
*/
@@ -46,6 +45,41 @@
/**
+ * @see IpClient#take
+ */
+ @POST
+ @Path("/ip/take/format/json")
+ ListenableFuture<Void> take(@FormParam("ipaddress") String ipAddress);
+
+
+ /**
+ * @see IpClient#release
+ */
+ @POST
+ @Path("/ip/release/format/json")
+ ListenableFuture<Void> release(@FormParam("ipaddress") String ipAddress);
+
+ /**
+ * @see IpClient#add
+ */
+ @POST
+ @Path("/ip/add/format/json")
+ ListenableFuture<Void> addIpToServer(@FormParam("ipaddress") String ipAddress,
+ @FormParam("serverid") String serverId);
+
+
+ /**
+ * @see IpClient#remove
+ *
+ * TODO: add optional release_ip parameter
+ */
+ @POST
+ @Path("/ip/remove/format/json")
+ ListenableFuture<Void> removeIpFromServer(@FormParam("ipaddress") String ipAddress,
+ @FormParam("serverid") String serverId);
+
+
+ /**
* @see IpClient#listFree
*/
@GET
@@ -64,7 +98,7 @@
@Path("/ip/details/ipaddress/{ipaddress}/format/json")
@Consumes(MediaType.APPLICATION_JSON)
@SelectJson("details")
- @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<IpDetails> getIpDetails(@PathParam("ipaddress") String ipAddress);
}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java
index 394c32d..0ada33d 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java
@@ -28,32 +28,67 @@
* Provides synchronous access to IP Addresses.
* <p/>
*
- * @author Adrian Cole
+ * @author Adrian Cole, Mattias Holmqvist
* @see IpAsyncClient
* @see <a href="https://customer.glesys.com/api.php" />
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface IpClient {
+ /**
+ * Take a free IP address and add it to this account. You can list free IP addresses with the function listFree().
+ * Once your free IP on this account you can add it to a server with the add() function.
+ *
+ * @param ipAddress
+ */
+ void take(String ipAddress);
- /**
- * Get a set of all IP addresses that are available and not used on any account or server.
- *
- * @param ipversion "4" or "6", for IPV4 or IPV6, respectively
- * @param datacenter the datacenter
- * @param platform the platform
- * @return a set of free IP addresses
- */
- Set<String> listFree(String ipversion, String datacenter, String platform);
+ /**
+ * Return an unused IP address to the pool of free ips. If the IP address is allocated to a server,
+ * it must first be removed by calling remove(ipAddress) before it can be released.
+ *
+ * @param ipAddress the IP address to be released
+ */
+ void release(String ipAddress);
- /**
- * Get details about the given IP address such as gateway and netmask. Different details are available
- * on different platforms.
- *
- * @param ipAddress the ip address
- * @return details about the given IP saddress
- */
- IpDetails getIpDetails(String ipAddress);
+ /**
+ * Add an IP address to an server. The IP has to be free, but reserved to this account. You are able to list such addresses
+ * with listOwn() and reserve an address for this account by using take(). To find free ips you can use ip/listfree
+ * ip to an Xen-server you have to configure the server yourself, unless the ip was added during the c
+ * server (server/create). You can get detailed information such as gateway and netmask using the ip
+ *
+ * @param ipAddress the IP address to remove
+ * @param serverId the server to add the IP address to
+ */
+ void addIpToServer(String ipAddress, String serverId);
+ /**
+ * Remove an IP address from a server. This does not release it back to GleSYS pool of free ips. The address will be
+ * kept on the account so that you can use it for other servers or the same server at a later time. To completely remove
+ * the IP address from this account, use the function release().
+ *
+ * @param ipAddress the IP address to remove
+ * @param serverId the server to remove the IP address from
+ */
+ void removeIpFromServer(String ipAddress, String serverId);
+
+ /**
+ * Get a set of all IP addresses that are available and not used on any account or server.
+ *
+ * @param ipversion "4" or "6", for IPV4 or IPV6, respectively
+ * @param datacenter the datacenter
+ * @param platform the platform
+ * @return a set of free IP addresses
+ */
+ Set<String> listFree(String ipversion, String datacenter, String platform);
+
+ /**
+ * Get details about the given IP address such as gateway and netmask. Different details are available
+ * on different platforms.
+ *
+ * @param ipAddress the ip address
+ * @return details about the given IP address
+ */
+ IpDetails getIpDetails(String ipAddress);
}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerAsyncClient.java
index df12c4c..02c7fe5 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerAsyncClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerAsyncClient.java
@@ -18,19 +18,41 @@
*/
package org.jclouds.glesys.features;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.jclouds.glesys.domain.*;
-import org.jclouds.glesys.options.*;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.glesys.domain.Server;
+import org.jclouds.glesys.domain.ServerAllowedArguments;
+import org.jclouds.glesys.domain.ServerConsole;
+import org.jclouds.glesys.domain.ServerCreated;
+import org.jclouds.glesys.domain.ServerDetails;
+import org.jclouds.glesys.domain.ServerLimit;
+import org.jclouds.glesys.domain.ServerStatus;
+import org.jclouds.glesys.domain.ServerTemplate;
+import org.jclouds.glesys.functions.ParseServerTemplatesFromHttpResponse;
+import org.jclouds.glesys.options.ServerCloneOptions;
+import org.jclouds.glesys.options.ServerCreateOptions;
+import org.jclouds.glesys.options.ServerDestroyOptions;
+import org.jclouds.glesys.options.ServerEditOptions;
+import org.jclouds.glesys.options.ServerStatusOptions;
+import org.jclouds.glesys.options.ServerStopOptions;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
-import javax.ws.rs.*;
-import javax.ws.rs.core.MediaType;
-import java.util.*;
+import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Server via their REST API.
@@ -90,7 +112,7 @@
*/
@POST
@Path("/server/console/format/json")
- @SelectJson("server")
+ @SelectJson("remote")
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<ServerConsole> getServerConsole(@FormParam("serverid") String id);
@@ -110,9 +132,9 @@
*/
@GET
@Path("/server/templates/format/json")
- @SelectJson("templates")
+ @ResponseParser(ParseServerTemplatesFromHttpResponse.class)
@Consumes(MediaType.APPLICATION_JSON)
- ListenableFuture<Map<String, Set<ServerTemplate>>> getTemplates();
+ ListenableFuture<Set<ServerTemplate>> getTemplates();
/**
* @see ServerClient#stopServer
@@ -183,7 +205,7 @@
*/
@POST
@Path("/server/destroy/format/json")
- ListenableFuture<Void> destroyServer(@FormParam("serverid") String id, @FormParam("keepip") int keepIp);
+ ListenableFuture<Void> destroyServer(@FormParam("serverid") String id, ServerDestroyOptions keepIp);
/**
* @see ServerClient#resetPassword
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerClient.java
index 554af8d..8d0b966 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerClient.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/ServerClient.java
@@ -18,16 +18,28 @@
*/
package org.jclouds.glesys.features;
-import org.jclouds.concurrent.Timeout;
-import org.jclouds.glesys.domain.*;
-import org.jclouds.glesys.options.*;
-import org.jclouds.javax.annotation.Nullable;
-
-import javax.ws.rs.FormParam;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import javax.ws.rs.FormParam;
+
+import org.jclouds.concurrent.Timeout;
+import org.jclouds.glesys.domain.Server;
+import org.jclouds.glesys.domain.ServerAllowedArguments;
+import org.jclouds.glesys.domain.ServerConsole;
+import org.jclouds.glesys.domain.ServerCreated;
+import org.jclouds.glesys.domain.ServerDetails;
+import org.jclouds.glesys.domain.ServerLimit;
+import org.jclouds.glesys.domain.ServerStatus;
+import org.jclouds.glesys.domain.ServerTemplate;
+import org.jclouds.glesys.options.ServerCloneOptions;
+import org.jclouds.glesys.options.ServerCreateOptions;
+import org.jclouds.glesys.options.ServerDestroyOptions;
+import org.jclouds.glesys.options.ServerEditOptions;
+import org.jclouds.glesys.options.ServerStatusOptions;
+import org.jclouds.glesys.options.ServerStopOptions;
+
/**
* Provides synchronous access to Server.
* <p/>
@@ -169,9 +181,9 @@
* Destroy a server
*
* @param id the id of the server
- * @param keepIp if 1 the servers ip will be retained for use in your Glesys account
+ * @param keepIp if ServerDestroyOptions.keepIp(true) the servers ip will be retained for use in your GleSYS account
*/
- void destroyServer(String id, int keepIp);
+ void destroyServer(String id, ServerDestroyOptions keepIp);
/**
* Reset the root password of a server
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/ParseServerTemplatesFromHttpResponse.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/ParseServerTemplatesFromHttpResponse.java
new file mode 100644
index 0000000..58e6481
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/ParseServerTemplatesFromHttpResponse.java
@@ -0,0 +1,59 @@
+/**
+ * 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.glesys.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.jclouds.glesys.domain.ServerTemplate;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.functions.ParseFirstJsonValueNamed;
+import org.jclouds.json.internal.GsonWrapper;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+
+/**
+ * @author Adrian Cole
+ */
+@Singleton
+public class ParseServerTemplatesFromHttpResponse implements Function<HttpResponse, Set<ServerTemplate>> {
+ private final ParseFirstJsonValueNamed<Map<String, Set<ServerTemplate>>> parser;
+
+ @Inject
+ public ParseServerTemplatesFromHttpResponse(GsonWrapper gsonWrapper) {
+ this.parser = new ParseFirstJsonValueNamed<Map<String, Set<ServerTemplate>>>(checkNotNull(gsonWrapper,
+ "gsonWrapper"), new TypeLiteral<Map<String, Set<ServerTemplate>>>() {
+ }, "templates");
+ }
+
+ public Set<ServerTemplate> apply(HttpResponse response) {
+ checkNotNull(response, "response");
+ Map<String, Set<ServerTemplate>> toParse = parser.apply(response);
+ checkNotNull(toParse, "parsed result from %s", response);
+ return ImmutableSet.copyOf(Iterables.concat(toParse.values()));
+ }
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/CustomDeserializers.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/CustomDeserializers.java
deleted file mode 100644
index dd4b477..0000000
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/CustomDeserializers.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.jclouds.glesys.functions.internal;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import org.jclouds.glesys.domain.ServerState;
-import org.jclouds.glesys.domain.ServerUptime;
-
-import java.lang.reflect.Type;
-
-/**
- * @author Adam Lowe
- */
-public class CustomDeserializers {
-
- public static class ServerStateAdapter implements JsonDeserializer<ServerState> {
- @Override
- public ServerState deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context)
- throws JsonParseException {
- String toParse = jsonElement.getAsJsonPrimitive().getAsString();
- return ServerState.fromValue(toParse);
- }
- }
-
- public static class ServerUptimeAdaptor implements JsonDeserializer<ServerUptime> {
- @Override
- public ServerUptime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context)
- throws JsonParseException {
- String toParse = jsonElement.getAsJsonPrimitive().getAsString();
- return ServerUptime.fromValue(toParse);
- }
- }
-}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GleSYSTypeAdapters.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GleSYSTypeAdapters.java
new file mode 100644
index 0000000..b1e26bb
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GleSYSTypeAdapters.java
@@ -0,0 +1,58 @@
+/**
+ * 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.glesys.functions.internal;
+
+import java.io.IOException;
+
+import org.jclouds.glesys.domain.ServerState;
+import org.jclouds.glesys.domain.ServerUptime;
+
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * @author Adam Lowe
+ */
+public class GleSYSTypeAdapters {
+
+ public static class ServerStateAdapter extends TypeAdapter<ServerState> {
+ @Override
+ public void write(JsonWriter writer, ServerState value) throws IOException {
+ writer.value(value.value());
+ }
+
+ @Override
+ public ServerState read(JsonReader reader) throws IOException {
+ return ServerState.fromValue(reader.nextString());
+ }
+ }
+
+ public static class ServerUptimeAdapter extends TypeAdapter<ServerUptime> {
+ @Override
+ public void write(JsonWriter writer, ServerUptime value) throws IOException {
+ writer.value(value.toString());
+ }
+
+ @Override
+ public ServerUptime read(JsonReader reader) throws IOException {
+ return ServerUptime.fromValue(reader.nextString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GlesysDateAdapter.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GlesysDateAdapter.java
index 6568b65..6b7bb1a 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GlesysDateAdapter.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/functions/internal/GlesysDateAdapter.java
@@ -1,39 +1,60 @@
+/**
+ * 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.glesys.functions.internal;
-import com.google.gson.*;
-import org.jclouds.json.config.GsonModule;
-
-import javax.inject.Singleton;
-import java.lang.reflect.Type;
+import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import javax.inject.Singleton;
+
+import org.jclouds.json.config.GsonModule;
+
+import com.google.common.base.Throwables;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
/**
* Parser for Glesys Date formats
*
* @author Adam Lowe
*/
@Singleton
-public class GlesysDateAdapter implements GsonModule.DateAdapter {
+public class GlesysDateAdapter extends GsonModule.DateAdapter {
private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
+ public void write(JsonWriter writer, Date value) throws IOException {
synchronized (dateFormat) {
- return new JsonPrimitive(dateFormat.format(src));
+ writer.value(dateFormat.format(value));
}
}
- public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- String toParse = json.getAsJsonPrimitive().getAsString();
+ public Date read(JsonReader reader) throws IOException {
+ String toParse = reader.nextString();
try {
synchronized (dateFormat) {
return dateFormat.parse(toParse);
}
} catch (ParseException e) {
- throw new RuntimeException(e);
+ throw Throwables.propagate(e);
}
}
}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainOptions.java
index a7e8deb..6bc47aa 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordAddOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordAddOptions.java
index 8ab0236..fc304b8 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordAddOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordAddOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordModifyOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordModifyOptions.java
index 905219f..50e46d9 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordModifyOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/DomainRecordModifyOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
/**
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailCreateOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailCreateOptions.java
new file mode 100644
index 0000000..b253f6c
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailCreateOptions.java
@@ -0,0 +1,89 @@
+/**
+ * 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.glesys.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_createaccount" />
+ */
+public class EmailCreateOptions extends BaseHttpRequestOptions {
+ public static class Builder {
+ /**
+ * @see EmailCreateOptions#antispamLevel
+ */
+ public static EmailCreateOptions antispamLevel(int antispamLevel) {
+ return new EmailCreateOptions().antispamLevel(antispamLevel);
+ }
+
+ /**
+ * @see EmailCreateOptions#antiVirus
+ */
+ public static EmailCreateOptions antiVirus(boolean antiVirus) {
+ return new EmailCreateOptions().antiVirus(antiVirus);
+ }
+
+ /**
+ * @see EmailCreateOptions#autorespond
+ */
+ public static EmailCreateOptions autorespond(boolean autorespond) {
+ return new EmailCreateOptions().autorespond(autorespond);
+ }
+
+ /**
+ * @see EmailCreateOptions#autorespondSaveEmail
+ */
+ public static EmailCreateOptions autorespondSaveEmail(boolean autorespondSaveEmail) {
+ return new EmailCreateOptions().autorespondSaveEmail(autorespondSaveEmail);
+ }
+
+ /**
+ * @see EmailCreateOptions#autorespondMessage
+ */
+ public static EmailCreateOptions autorespondMessage(boolean autorespondMessage) {
+ return new EmailCreateOptions().autorespondMessage(autorespondMessage);
+ }
+ }
+
+ public EmailCreateOptions antispamLevel(int antispamLevel) {
+ formParameters.put("antispamlevel", Integer.toString(antispamLevel));
+ return this;
+ }
+
+ public EmailCreateOptions antiVirus(boolean antiVirus) {
+ formParameters.put("antivirus", Integer.toString(antiVirus ? 1 : 0));
+ return this;
+ }
+
+ public EmailCreateOptions autorespond(boolean autorespond) {
+ formParameters.put("autorespond", Integer.toString(autorespond ? 1 : 0));
+ return this;
+ }
+
+ public EmailCreateOptions autorespondSaveEmail(boolean autorespondSaveEmail) {
+ formParameters.put("autorespondsaveemail", Integer.toString(autorespondSaveEmail ? 1 : 0));
+ return this;
+ }
+
+ public EmailCreateOptions autorespondMessage(boolean autorespondMessage) {
+ formParameters.put("autorespondmessage", Integer.toString(autorespondMessage ? 1 : 0));
+ return this;
+ }
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailEditOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailEditOptions.java
new file mode 100644
index 0000000..97f0e90
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/EmailEditOptions.java
@@ -0,0 +1,58 @@
+/**
+ * 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.glesys.options;
+
+
+/**
+ * @author Adam Lowe
+ * @see <a href="https://customer.glesys.com/api.php?a=doc#email_editaccount" />
+ */
+public class EmailEditOptions extends EmailCreateOptions {
+
+ public static class Builder {
+ public static EmailEditOptions antispamLevel(int antispamLevel) {
+ return EmailEditOptions.class.cast(new EmailEditOptions().antispamLevel(antispamLevel));
+ }
+
+ public static EmailEditOptions antiVirus(boolean antiVirus) {
+ return EmailEditOptions.class.cast(new EmailEditOptions().antiVirus(antiVirus));
+ }
+
+ public static EmailEditOptions autorespond(boolean autorespond) {
+ return EmailEditOptions.class.cast(new EmailEditOptions().autorespond(autorespond));
+ }
+
+ public static EmailEditOptions autorespondSaveEmail(boolean autorespondSaveEmail) {
+ return EmailEditOptions.class.cast(new EmailEditOptions().autorespondSaveEmail(autorespondSaveEmail));
+ }
+
+ public static EmailEditOptions autorespondMessage(boolean autorespondMessage) {
+ return EmailEditOptions.class.cast(new EmailEditOptions().autorespondMessage(autorespondMessage));
+ }
+
+ public static EmailEditOptions autorespondMessage(String password) {
+ return new EmailEditOptions().password(password);
+ }
+ }
+
+ public EmailEditOptions password(String password) {
+ formParameters.put("password", password);
+ return this;
+ }
+}
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCloneOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCloneOptions.java
index 25d877e..388a49d 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCloneOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCloneOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
/**
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCreateOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCreateOptions.java
index 858f393..aeedd44 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCreateOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerCreateOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerDestroyOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerDestroyOptions.java
new file mode 100644
index 0000000..62099dd
--- /dev/null
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerDestroyOptions.java
@@ -0,0 +1,53 @@
+/**
+ * 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.glesys.options;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * @author Adam Lowe
+ */
+public class ServerDestroyOptions extends BaseHttpRequestOptions {
+ public static class Builder {
+ /**
+ * Discard the server's ip on destroy
+ */
+ public static ServerDestroyOptions keepIp() {
+ return new ServerDestroyOptions().keepIp(true);
+ }
+
+ /**
+ * Discard the server's ip on destroy
+ */
+ public static ServerDestroyOptions discardIp() {
+ return new ServerDestroyOptions().keepIp(false);
+ }
+
+ }
+
+ /**
+ * Determines whether to keep the server's ip attached to your account when destroying a server
+ *
+ * @param keepIp if true, keep the ip address
+ */
+ public ServerDestroyOptions keepIp(boolean keepIp) {
+ formParameters.put("keepip", Integer.toString(keepIp ? 1 : 0));
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerEditOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerEditOptions.java
index 3518fbe..b45070b 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerEditOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerEditOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStatusOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStatusOptions.java
index c923e04..bc13482 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStatusOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStatusOptions.java
@@ -1,6 +1,23 @@
+/**
+ * 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.glesys.options;
-import com.google.common.collect.Iterables;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStopOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStopOptions.java
index b8c337c..1e81f49 100644
--- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStopOptions.java
+++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/options/ServerStopOptions.java
@@ -1,3 +1,21 @@
+/**
+ * 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.glesys.options;
/**
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveAsyncClientTest.java
index 6c6c7bd..124f4ec 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveAsyncClientTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveAsyncClientTest.java
@@ -18,15 +18,15 @@
*/
package org.jclouds.glesys.features;
-import com.google.inject.TypeLiteral;
+import java.util.Map;
+
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
-import javax.ws.rs.FormParam;
-import java.util.Map;
+import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code ArchiveAsyncClient}
@@ -47,7 +47,7 @@
}
public void testArchiveDetails() throws Exception {
- testMethod("archiveDetails", "details", "POST", true, ReturnNullOnNotFoundOr404.class, userName);
+ testMethod("getArchiveDetails", "details", "POST", true, ReturnNullOnNotFoundOr404.class, userName);
}
public void testCreateArchive() throws Exception {
@@ -61,7 +61,7 @@
public void testResizeArchive() throws Exception {
testMethod("resizeArchive", "resize", "POST", false, MapHttp4xxCodesToExceptions.class, userName,
- newEntry("size", 5));
+ newEntry("size", "5 GB"));
}
public void testChangeArchivePassword() throws Exception {
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveClientLiveTest.java
index 0931ba6..31b6299 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveClientLiveTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ArchiveClientLiveTest.java
@@ -18,28 +18,27 @@
*/
package org.jclouds.glesys.features;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import org.jclouds.glesys.domain.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.glesys.domain.ArchiveAllowedArguments;
+import org.jclouds.glesys.domain.ArchiveDetails;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Predicates.equalTo;
-import static org.testng.Assert.*;
+import com.google.common.base.Predicate;
/**
* Tests behavior of {@code ArchiveClient}
*
* @author Adam Lowe
*/
-@Test(groups = "live", testName = "ArchiveClientLiveTest")
+@Test(groups = "live", testName = "ArchiveClientLiveTest", singleThreaded = true)
public class ArchiveClientLiveTest extends BaseGleSYSClientLiveTest {
@BeforeGroups(groups = {"live"})
@@ -97,7 +96,7 @@
@Test(dependsOnMethods = "testCreateArchive")
public void testArchiveDetails() throws Exception {
- ArchiveDetails details = client.archiveDetails(archiveUser);
+ ArchiveDetails details = client.getArchiveDetails(archiveUser);
assertEquals(details.getUsername(), archiveUser);
assertNotNull(details.getFreeSize());
assertNotNull(details.getTotalSize());
@@ -109,15 +108,14 @@
// TODO assert something useful!
}
- // TODO enable this once issue is resolved
- @Test(enabled=false, dependsOnMethods = "testCreateArchive")
+ @Test(dependsOnMethods = "testCreateArchive")
public void testResizeArchive() throws Exception {
- client.resizeArchive(archiveUser, 30);
+ client.resizeArchive(archiveUser, 20);
assertTrue(new RetryablePredicate<String>(
new Predicate<String>() {
public boolean apply(String value){
- return client.archiveDetails(archiveUser) != null && value.equals(client.archiveDetails(archiveUser).getTotalSize());
+ return client.getArchiveDetails(archiveUser) != null && value.equals(client.getArchiveDetails(archiveUser).getTotalSize());
}
}, 30, 1, TimeUnit.SECONDS).apply("20 GB"));
}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSAsyncClientTest.java
index a481233..26e799a 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSAsyncClientTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSAsyncClientTest.java
@@ -18,9 +18,16 @@
*/
package org.jclouds.glesys.features;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Maps;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
import org.jclouds.glesys.GleSYSAsyncClient;
import org.jclouds.glesys.GleSYSClient;
import org.jclouds.http.HttpRequest;
@@ -30,21 +37,18 @@
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
+import org.jclouds.util.Strings2;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import static org.testng.Assert.*;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Maps;
/**
* @author Adrian Cole
* @author Adam Lowe
*/
public abstract class BaseGleSYSAsyncClientTest<T> extends RestClientTest<T> {
- protected Class asyncClientClass;
+ protected Class<T> asyncClientClass;
protected String remoteServicePrefix;
@Override
@@ -58,7 +62,8 @@
Properties props = new Properties();
return new RestContextFactory().createContextSpec("glesys", "username", "apiKey", props);
}
-
+
+ @Deprecated
protected Map.Entry<String, String> newEntry(String key, Object value) {
return Maps.immutableEntry(key, value.toString());
}
@@ -66,8 +71,6 @@
/**
* Test that a method call is annotated correctly.
* <p/>
- * TODO de-code ampersands and spaces in args properly
- *
* @param localMethod the method to call in asyncClientClass
* @param remoteCall the name of the expected call on the remote server
* @param httpMethod "GET" or "POST"
@@ -75,7 +78,17 @@
* @param exceptionParser the class of exception handler expected
* @param args either Map.Entry or BaseHttpRequestOptions that make up the arguments to the method
*/
- protected void testMethod(String localMethod, String remoteCall, String httpMethod, boolean expectResponse, Class exceptionParser, Object... args) throws Exception {
+ //TODO: kill this and related logic and transition to BaseRestClientExpectTest<GleSYSClient>
+ @Deprecated
+ protected void testMethod(String localMethod, String remoteCall, String httpMethod, boolean expectResponse,
+ Class<?> exceptionParser, Object... args) throws Exception {
+ testMethod(localMethod, remoteCall, httpMethod, expectResponse, ParseFirstJsonValueNamed.class, exceptionParser,
+ args);
+ }
+
+ @Deprecated
+ @SuppressWarnings("unchecked")
+ protected void testMethod(String localMethod, String remoteCall, String httpMethod, boolean expectResponse, Class<?> responseParser, Class<?> exceptionParser, Object... args) throws Exception {
List<String> argStrings = new ArrayList<String>();
List<Object> argValues = new ArrayList<Object>();
@@ -87,7 +100,7 @@
argValues.add(arg);
} else {
Map.Entry<String, String> entry = (Map.Entry<String, String>) arg;
- argStrings.add(entry.getKey() + "=" + entry.getValue());
+ argStrings.add(entry.getKey() + "=" + Strings2.urlEncode(entry.getValue()));
argValues.add(entry.getValue());
}
}
@@ -108,7 +121,7 @@
if (expectResponse) {
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
- assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
+ assertResponseParserClassEquals(method, httpRequest, responseParser);
}
if (argStrings.isEmpty()) {
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSClientLiveTest.java
index 206ca54..4e607f4 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSClientLiveTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/BaseGleSYSClientLiveTest.java
@@ -19,10 +19,17 @@
package org.jclouds.glesys.features;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.*;
+import com.google.common.base.Predicate;
import org.jclouds.glesys.GleSYSAsyncClient;
import org.jclouds.glesys.GleSYSClient;
+import org.jclouds.glesys.domain.ServerCreated;
+import org.jclouds.glesys.domain.ServerState;
+import org.jclouds.glesys.domain.ServerStatus;
+import org.jclouds.glesys.options.ServerStatusOptions;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
+import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.sshj.config.SshjSshClientModule;
@@ -33,10 +40,12 @@
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests behavior of {@code GleSYSClient}
*
- * @author Adrian Cole
+ * @author Adrian Cole, Adam Lowe
*/
@Test(groups = "live")
public class BaseGleSYSClientLiveTest {
@@ -45,18 +54,67 @@
@BeforeGroups(groups = { "live" })
public void setupClient() {
- String identity = checkNotNull(System.getProperty("test.glesys.identity"), "test.glesys.identity");
- String credential = checkNotNull(System.getProperty("test.glesys.credential"), "test.glesys.credential");
-
- context = new RestContextFactory().createContext("glesys", identity, credential,
- ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
-
+ if (context == null) {
+ String identity = checkNotNull(System.getProperty("test.glesys.identity"), "test.glesys.identity");
+ String credential = checkNotNull(System.getProperty("test.glesys.credential"), "test.glesys.credential");
+
+ context = new RestContextFactory().createContext("glesys", identity, credential,
+ ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
+ }
}
@AfterGroups(groups = "live")
protected void tearDown() {
- if (context != null)
+ if (context != null) {
context.close();
+ context = null;
+ }
}
+ protected void createDomain(String domain) {
+ final DomainClient client = context.getApi().getDomainClient();
+ int before = client.listDomains().size();
+ client.addDomain(domain);
+ RetryablePredicate<Integer> result = new RetryablePredicate<Integer>(
+ new Predicate<Integer>() {
+ public boolean apply(Integer value) {
+ return client.listDomains().size() == value;
+ }
+ }, 30, 1, TimeUnit.SECONDS);
+
+ assertTrue(result.apply(before + 1));
+ }
+
+
+ protected ServerStatusChecker createServer(String hostName) {
+ ServerClient client = context.getApi().getServerClient();
+ ServerCreated testServer = client.createServer("Falkenberg", "OpenVZ", hostName, "Ubuntu 10.04 LTS 32-bit", 5, 512, 1, "password", 50);
+
+ assertNotNull(testServer.getId());
+ assertEquals(testServer.getHostname(), hostName);
+ assertFalse(testServer.getIps().isEmpty());
+
+ ServerStatusChecker runningServerCounter = new ServerStatusChecker(client, testServer.getId(), 180, 10, TimeUnit.SECONDS);
+
+ assertTrue(runningServerCounter.apply(ServerState.RUNNING));
+ return runningServerCounter;
+ }
+
+ public static class ServerStatusChecker extends RetryablePredicate<ServerState> {
+ private final String serverId;
+ public String getServerId() {
+ return serverId;
+ }
+ public ServerStatusChecker(final ServerClient client, final String serverId, long maxWait, long period, TimeUnit unit) {
+ super(new Predicate<ServerState>() {
+
+ public boolean apply(ServerState value) {
+ ServerStatus status = client.getServerStatus(serverId, ServerStatusOptions.Builder.state());
+ return status.getState() == value;
+ }
+
+ }, maxWait, period, unit);
+ this.serverId = serverId;
+ }
+ }
}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainAsyncClientTest.java
index 5cb73e7..e945854 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainAsyncClientTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainAsyncClientTest.java
@@ -18,15 +18,15 @@
*/
package org.jclouds.glesys.features;
-import com.google.inject.TypeLiteral;
+import java.util.Map;
+
import org.jclouds.glesys.options.DomainOptions;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
-import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
-import java.util.Map;
+import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code DomainAsyncClient}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainClientLiveTest.java
index 14459ae..4ab2e64 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainClientLiveTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/DomainClientLiveTest.java
@@ -18,25 +18,27 @@
*/
package org.jclouds.glesys.features;
-import com.google.common.base.Predicate;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
import org.jclouds.glesys.domain.DomainRecord;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import static org.testng.Assert.assertTrue;
+import com.google.common.base.Predicate;
/**
* Tests behavior of {@code DomainClient}
*
* @author Adam Lowe
*/
-@Test(groups = "live", testName = "DomainClientLiveTest")
+@Test(groups = "live", testName = "DomainClientLiveTest", singleThreaded = true)
public class DomainClientLiveTest extends BaseGleSYSClientLiveTest {
+ public final String testDomain = "glesystest.jclouds.org";
@BeforeGroups(groups = {"live"})
public void setupClient() {
@@ -55,6 +57,13 @@
return client.listRecords(testDomain).size() == value;
}
}, 30, 1, TimeUnit.SECONDS);
+
+ try {
+ client.deleteDomain(testDomain);
+ } catch (Exception ex) {
+ }
+
+ createDomain(testDomain);
}
@AfterGroups(groups = {"live"})
@@ -67,24 +76,10 @@
}
private DomainClient client;
- private String testDomain = "glesystest.jclouds.org";
- private String testRecordId;
private RetryablePredicate<Integer> domainCounter;
private RetryablePredicate<Integer> recordCounter;
@Test
- public void testCreateDomain() throws Exception {
- try {
- client.deleteDomain(testDomain);
- } catch (Exception ex) {
- }
-
- int before = client.listDomains().size();
- client.addDomain(testDomain);
- assertTrue(domainCounter.apply(before + 1));
- }
-
- @Test(dependsOnMethods = "testCreateDomain")
public void testCreateRecord() throws Exception {
int before = client.listRecords(testDomain).size();
@@ -93,7 +88,7 @@
assertTrue(recordCounter.apply(before + 1));
}
- @Test(dependsOnMethods = "testCreateRecord")
+ @Test
public void testDeleteRecord() throws Exception {
Set<DomainRecord> domainRecords = client.listRecords(testDomain);
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailAsyncClientTest.java
new file mode 100644
index 0000000..84fb0ca
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailAsyncClientTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.glesys.features;
+
+import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
+import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
+import org.jclouds.rest.internal.RestAnnotationProcessor;
+import org.testng.annotations.Test;
+
+import com.google.inject.TypeLiteral;
+
+/**
+ * Tests annotation parsing of {@code ArchiveAsyncClient}
+ *
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "EmailAsyncClientTest")
+public class EmailAsyncClientTest extends BaseGleSYSAsyncClientTest<EmailAsyncClient> {
+ public EmailAsyncClientTest() {
+ asyncClientClass = EmailAsyncClient.class;
+ remoteServicePrefix = "email";
+ }
+
+ public void testList() throws Exception {
+ testMethod("listAccounts", "list", "POST", true, ReturnEmptySetOnNotFoundOr404.class, newEntry("domain","test"));
+ }
+
+ public void testOverview() throws Exception {
+ testMethod("getEmailOverview", "overview", "POST", true, ReturnEmptySetOnNotFoundOr404.class);
+ }
+
+ public void testCreateAccount() throws Exception {
+ testMethod("createAccount", "createaccount", "POST", false, MapHttp4xxCodesToExceptions.class,
+ newEntry("emailaccount", "jclouds.org"), newEntry("password", "test@jclouds.org"));
+ }
+
+ public void testCreateAlias() throws Exception {
+ testMethod("createAlias", "createalias", "POST", false, MapHttp4xxCodesToExceptions.class,
+ newEntry("emailalias", "test2@jclouds.org"), newEntry("goto", "test@jclouds.org"));
+ }
+
+ public void testEditAlias() throws Exception {
+ testMethod("editAlias", "editalias", "POST", false, MapHttp4xxCodesToExceptions.class,
+ newEntry("emailalias", "test2@jclouds.org"), newEntry("goto", "test1@jclouds.org"));
+ }
+
+ @Override
+ protected TypeLiteral<RestAnnotationProcessor<EmailAsyncClient>> createTypeLiteral() {
+ return new TypeLiteral<RestAnnotationProcessor<EmailAsyncClient>>() {
+ };
+ }
+}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailClientLiveTest.java
new file mode 100644
index 0000000..845d173
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/EmailClientLiveTest.java
@@ -0,0 +1,157 @@
+/**
+ * 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.
+ */
+/**
+* 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.glesys.features;
+
+import com.google.common.base.Predicate;
+import org.jclouds.glesys.domain.*;
+import org.jclouds.glesys.options.EmailCreateOptions;
+import org.jclouds.glesys.options.EmailEditOptions;
+import org.jclouds.glesys.options.ServerDestroyOptions;
+import org.jclouds.predicates.RetryablePredicate;
+import org.testng.annotations.AfterGroups;
+import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.Test;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static org.testng.Assert.*;
+
+/**
+* Tests behavior of {@code EmailClient}
+*
+* @author Adam Lowe
+*/
+@Test(groups = "live", testName = "EmailClientLiveTest", singleThreaded = true)
+public class EmailClientLiveTest extends BaseGleSYSClientLiveTest {
+
+ @BeforeGroups(groups = {"live"})
+ public void setupClient() {
+ super.setupClient();
+ client = context.getApi().getEmailClient();
+
+ try {
+ client.delete("test@" + testDomain);
+ client.delete("test2@" + testDomain);
+ context.getApi().getDomainClient().deleteDomain(testDomain);
+ } catch(Exception e) {
+ }
+
+ serverId = createServer("test-email-jclouds").getServerId();
+
+ createDomain(testDomain);
+
+ emailAccountCounter = new RetryablePredicate<Integer>(
+ new Predicate<Integer>() {
+ public boolean apply(Integer value) {
+ return client.listAccounts(testDomain).size() == value;
+ }
+ }, 30, 1, TimeUnit.SECONDS);
+
+ }
+
+
+ @AfterGroups(groups = {"live"})
+ public void tearDown() {
+ client.delete("test@" + testDomain);
+ assertTrue(emailAccountCounter.apply(0));
+ context.getApi().getDomainClient().deleteDomain(testDomain);
+ context.getApi().getServerClient().destroyServer(serverId, ServerDestroyOptions.Builder.discardIp());
+ super.tearDown();
+ }
+
+ private EmailClient client;
+ private String serverId;
+ private final String testDomain = "email-test.jclouds.org";
+ private RetryablePredicate<Integer> emailAccountCounter;
+
+ @Test
+ public void createEmail() {
+ client.createAccount("test@" + testDomain, "password", EmailCreateOptions.Builder.antiVirus(true));
+ assertTrue(emailAccountCounter.apply(1));
+ }
+
+ @Test(dependsOnMethods = "createEmail")
+ public void createAlias() {
+ client.createAlias("test2@" + testDomain, "test@" + testDomain);
+ EmailOverview overview = client.getEmailOverview();
+ assertTrue(overview.getSummary().getAliases() == 1);
+ client.delete("test2@" + testDomain);
+ overview = client.getEmailOverview();
+ assertTrue(overview.getSummary().getAliases() == 0);
+ }
+
+ @Test(dependsOnMethods = "createEmail")
+ public void testOverview() throws Exception {
+ EmailOverview overview = client.getEmailOverview();
+ assertNotNull(overview.getSummary());
+ assertTrue(overview.getSummary().getAccounts() >= 1);
+ assertTrue(overview.getSummary().getAliases() == 0);
+ assertTrue(overview.getSummary().getMaxAccounts() > 0);
+ assertTrue(overview.getSummary().getMaxAliases() > 0);
+ assertNotNull(overview.getDomains());
+ assertFalse(overview.getDomains().isEmpty());
+
+ EmailOverviewDomain domain = EmailOverviewDomain.builder().domain(testDomain).accounts(1).build();
+ assertTrue(overview.getDomains().contains(domain));
+ }
+
+ @Test(dependsOnMethods = "createEmail")
+ public void testListAccounts() throws Exception {
+ Set<Email> accounts = client.listAccounts(testDomain);
+ assertTrue(accounts.size() >= 1);
+ }
+
+ @Test(dependsOnMethods = "createEmail")
+ public void testEditAccount() throws Exception {
+ Set<Email> accounts = client.listAccounts(testDomain);
+ for(Email account : accounts) {
+ if (account.getAccount().equals("test@" + testDomain)) {
+ assertTrue(account.getAntiVirus());
+ }
+ }
+
+ client.editAccount("test@" + testDomain, EmailEditOptions.Builder.antiVirus(false));
+
+ accounts = client.listAccounts(testDomain);
+ for(Email account : accounts) {
+ if (account.getAccount().equals("test@" + testDomain)) {
+ assertFalse(account.getAntiVirus());
+ }
+ }
+ }
+}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpAsyncClientTest.java
index b1bc619..6fcea5b 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpAsyncClientTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpAsyncClientTest.java
@@ -18,6 +18,12 @@
*/
package org.jclouds.glesys.features;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.functions.ParseFirstJsonValueNamed;
+import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
@@ -31,6 +37,22 @@
@Test(groups = "unit", testName = "IpAsyncClientTest")
public class IpAsyncClientTest extends BaseGleSYSAsyncClientTest<IpAsyncClient> {
+ public void testGetIpDetails() throws SecurityException, NoSuchMethodException, IOException {
+ Method method = IpAsyncClient.class.getMethod("getIpDetails", String.class);
+ HttpRequest request = processor.createRequest(method, "31.192.227.37");
+
+ assertRequestLineEquals(request,
+ "GET https://api.glesys.com/ip/details/ipaddress/31.192.227.37/format/json HTTP/1.1");
+ assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
+ assertPayloadEquals(request, null, "application/xml", false);
+
+ assertResponseParserClassEquals(method, request, ParseFirstJsonValueNamed.class);
+ assertSaxResponseParserClassEquals(method, null);
+ assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
+
+ checkFilters(request);
+ }
+
@Override
protected TypeLiteral<RestAnnotationProcessor<IpAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<IpAsyncClient>>() {
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientExpectTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientExpectTest.java
new file mode 100644
index 0000000..1f82c6c
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientExpectTest.java
@@ -0,0 +1,250 @@
+/**
+ * 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.glesys.features;
+
+import com.google.common.collect.ImmutableMultimap;
+import org.jclouds.glesys.GleSYSClient;
+import org.jclouds.glesys.domain.IpDetails;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpResponseException;
+import org.jclouds.rest.BaseRestClientExpectTest;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptySet;
+import static org.jclouds.io.Payloads.newUrlEncodedFormPayload;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+import static org.testng.collections.Sets.newHashSet;
+
+/**
+ * Allows us to test a client via its side effects.
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "IpClientExpectTest")
+public class IpClientExpectTest extends BaseRestClientExpectTest<GleSYSClient> {
+ public IpClientExpectTest() {
+ provider = "glesys";
+ }
+
+ public void testGetIpDetailsWhenResponseIs2xx() {
+
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://api.glesys.com/ip/details/ipaddress/31.192.227.37/format/json")).headers(
+ ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(),
+ HttpResponse.builder().statusCode(200).payload(payloadFromResource("/ip_get_details.json")).build())
+ .getIpClient();
+
+ assertEquals(client.getIpDetails("31.192.227.37"), IpDetails.builder().datacenter("Falkenberg").ipversion("4")
+ .platform("OpenVZ").ptr("31-192-227-37-static.serverhotell.net.").build());
+
+ }
+
+ public void testGetIpDetailsWhenResponseIs4xxReturnsNull() {
+
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://api.glesys.com/ip/details/ipaddress/31.192.227.37/format/json")).headers(
+ ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(),
+ HttpResponse.builder().statusCode(404).build()).getIpClient();
+
+ assertEquals(client.getIpDetails("31.192.227.37"), null);
+
+ }
+
+ public void testTakeWhenResponseIs2xx() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/take/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder()
+ .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder().put("ipaddress", "46.21.105.186").build()
+ )).build(),
+ HttpResponse.builder().statusCode(200).payload(payloadFromResource("/ip_take.json")).build())
+ .getIpClient();
+
+ client.take("46.21.105.186");
+ }
+
+ public void testTakeWhenResponseIs4xxThrowsResponseException() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/take/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder()
+ .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder().put("ipaddress", "46.21.105.186").build()
+ )).build(),
+ HttpResponse.builder().statusCode(400).build())
+ .getIpClient();
+
+ try {
+ client.take("46.21.105.186");
+ fail();
+ } catch (HttpResponseException e) {
+ // Expected
+ }
+ }
+
+ public void testReleaseWhenResponseIs2xx() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/release/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder()
+ .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder().put("ipaddress", "46.21.105.186").build()
+ )).build(),
+ HttpResponse.builder().statusCode(200).payload(payloadFromResource("/ip_release.json")).build())
+ .getIpClient();
+
+ client.release("46.21.105.186");
+ }
+
+ public void testReleaseWhenResponseIs4xxThrowsResponseException() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/release/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder()
+ .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder().put("ipaddress", "46.21.105.186").build()
+ )).build(),
+ HttpResponse.builder().statusCode(400).build())
+ .getIpClient();
+
+ try {
+ client.release("46.21.105.186");
+ fail();
+ } catch (HttpResponseException e) {
+ // Expected
+ }
+ }
+
+ public void testListFreeWhenResponseIs2xx() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://api.glesys.com/ip/listfree/ipversion/4/datacenter/Falkenberg/platform/OpenVZ/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(),
+ HttpResponse.builder().statusCode(200).payload(payloadFromResource("/ip_list_free.json")).build())
+ .getIpClient();
+
+ Set<Object> expectedIps = newHashSet();
+ expectedIps.addAll(asList("31.192.226.131", "31.192.226.133"));
+ assertEquals(client.listFree("4", "Falkenberg", "OpenVZ"), expectedIps);
+ }
+
+ public void testListFreeWhenResponseIs404ReturnsEmptySet() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("GET").endpoint(
+ URI.create("https://api.glesys.com/ip/listfree/ipversion/4/datacenter/Falkenberg/platform/OpenVZ/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(),
+ HttpResponse.builder().statusCode(404).build())
+ .getIpClient();
+
+ assertEquals(client.listFree("4", "Falkenberg", "OpenVZ"), emptySet());
+ }
+
+ public void testAddWhenResponseIs2xx() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/add/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder()
+ .put("ipaddress", "31.192.227.37")
+ .put("serverid", "vz1946889").build())).build(),
+ HttpResponse.builder().statusCode(200).build())
+ .getIpClient();
+
+ client.addIpToServer("31.192.227.37", "vz1946889");
+ }
+
+ public void testAddWhenResponseIs4xxThrowsHttpException() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/add/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder()
+ .put("ipaddress", "31.192.227.37")
+ .put("serverid", "vz1946889")
+ .build())).build(),
+ HttpResponse.builder().statusCode(400).build())
+ .getIpClient();
+
+ try {
+ client.addIpToServer("31.192.227.37", "vz1946889");
+ fail();
+ } catch (HttpResponseException e) {
+ // Expected
+ }
+ }
+
+ public void testRemoveWhenResponseIs2xx() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/remove/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder()
+ .put("ipaddress", "31.192.227.37")
+ .put("serverid", "vz1946889").build())).build(),
+ HttpResponse.builder().statusCode(200).build())
+ .getIpClient();
+
+ client.removeIpFromServer("31.192.227.37", "vz1946889");
+ }
+
+ public void testRemoveWhenResponseIs4xxThrowsHttpException() {
+ IpClient client = requestSendsResponse(
+ HttpRequest.builder().method("POST").endpoint(
+ URI.create("https://api.glesys.com/ip/remove/format/json"))
+ .headers(ImmutableMultimap.<String, String>builder().put(
+ "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
+ .payload(newUrlEncodedFormPayload(
+ ImmutableMultimap.<String, String>builder()
+ .put("ipaddress", "31.192.227.37")
+ .put("serverid", "vz1946889").build())).build(),
+ HttpResponse.builder().statusCode(400).build())
+ .getIpClient();
+
+ try {
+ client.removeIpFromServer("31.192.227.37", "vz1946889");
+ fail();
+ } catch (HttpResponseException e) {
+ // Expected
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerAsyncClientTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerAsyncClientTest.java
index 8a659e6..283c622 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerAsyncClientTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerAsyncClientTest.java
@@ -18,20 +18,22 @@
*/
package org.jclouds.glesys.features;
-import com.google.common.collect.Maps;
-import com.google.inject.TypeLiteral;
-import org.jclouds.glesys.options.*;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.functions.ParseFirstJsonValueNamed;
+import java.util.Map;
+
+import org.jclouds.glesys.functions.ParseServerTemplatesFromHttpResponse;
+import org.jclouds.glesys.options.ServerCloneOptions;
+import org.jclouds.glesys.options.ServerCreateOptions;
+import org.jclouds.glesys.options.ServerDestroyOptions;
+import org.jclouds.glesys.options.ServerEditOptions;
+import org.jclouds.glesys.options.ServerStatusOptions;
+import org.jclouds.glesys.options.ServerStopOptions;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.Map;
+import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code ServerAsyncClient}
@@ -58,7 +60,8 @@
}
public void testGetTemplates() throws Exception {
- testMethod("getTemplates", "templates", "GET", true, MapHttp4xxCodesToExceptions.class);
+ testMethod("getTemplates", "templates", "GET", true, ParseServerTemplatesFromHttpResponse.class,
+ MapHttp4xxCodesToExceptions.class);
}
public void testGetServer() throws Exception {
@@ -120,6 +123,11 @@
testMethod("rebootServer", "reboot", "POST", false, MapHttp4xxCodesToExceptions.class, serverIdOnly);
}
+ public void testDestroyServer() throws Exception {
+ testMethod("destroyServer", "destroy", "POST", false, MapHttp4xxCodesToExceptions.class, serverIdOnly, ServerDestroyOptions.Builder.keepIp());
+ testMethod("destroyServer", "destroy", "POST", false, MapHttp4xxCodesToExceptions.class, serverIdOnly, ServerDestroyOptions.Builder.discardIp());
+ }
+
@Override
protected TypeLiteral<RestAnnotationProcessor<ServerAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ServerAsyncClient>>() {
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientLiveTest.java
index 38e61c3..ee0230e 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientLiveTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientLiveTest.java
@@ -21,10 +21,12 @@
import com.google.common.base.Predicate;
import org.jclouds.glesys.domain.*;
import org.jclouds.glesys.options.ServerCloneOptions;
+import org.jclouds.glesys.options.ServerDestroyOptions;
import org.jclouds.glesys.options.ServerStatusOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.Map;
@@ -41,39 +43,34 @@
*/
@Test(groups = "live", testName = "ServerClientLiveTest")
public class ServerClientLiveTest extends BaseGleSYSClientLiveTest {
-
+ public static final String testHostName1 = "jclouds-test";
+ public static final String testHostName2 = "jclouds-test2";
+
@BeforeGroups(groups = {"live"})
public void setupClient() {
super.setupClient();
client = context.getApi().getServerClient();
+ serverStatusChecker = createServer(testHostName1);
+ testServerId = serverStatusChecker.getServerId();
}
@AfterGroups(groups = {"live"})
public void tearDown() {
- client.destroyServer(testServer.getId(), 0);
- if (testServer2 != null) {
- client.destroyServer(testServer2.getId(), 0);
+ client.destroyServer(testServerId, ServerDestroyOptions.Builder.discardIp());
+ if (testServerId2 != null) {
+ client.destroyServer(testServerId2, ServerDestroyOptions.Builder.discardIp());
}
super.tearDown();
}
private ServerClient client;
- private ServerCreated testServer;
- private ServerCreated testServer2;
- // note this is initialized by testCreateServer()
- private RetryablePredicate<ServerState> runningServerCounter;
+ private ServerStatusChecker serverStatusChecker;
+ private String testServerId;
+ private String testServerId2;
- @Test
- public void testCreateServer() throws Exception {
- testServer = client.createServer("Falkenberg", "OpenVZ", "jclouds-test", "Ubuntu 10.04 LTS 32-bit", 5, 512, 1, "password", 50);
-
- assertNotNull(testServer.getId());
- assertEquals(testServer.getHostname(), "jclouds-test");
- assertFalse(testServer.getIps().isEmpty());
-
- runningServerCounter = new ServerStatusChecker(testServer.getId(), 120, 2, TimeUnit.SECONDS);
-
- assertTrue(runningServerCounter.apply(ServerState.RUNNING));
+ @BeforeMethod
+ public void makeSureServerIsRunning() throws Exception {
+ serverStatusChecker.apply(ServerState.RUNNING);
}
@Test
@@ -125,7 +122,7 @@
assert t.getMinMemSize() > 0 : t;
}
- @Test(dependsOnMethods = "testCreateServer")
+ @Test
public void testListServers() throws Exception {
Set<Server> response = client.listServers();
assertNotNull(response);
@@ -141,35 +138,48 @@
}
}
- @Test(dependsOnMethods = "testCreateServer")
+ @Test
public void testServerDetails() throws Exception {
- ServerStatus newStatus = client.getServerStatus(testServer.getId());
+ ServerStatus newStatus = client.getServerStatus(testServerId);
checkStatus(newStatus);
}
- @Test(dependsOnMethods = "testCreateServer")
+ @Test(enabled=false) // TODO work a better plan
public void testRebootServer() throws Exception {
- client.rebootServer(testServer.getId());
+ long uptime = 0;
+
+ while(uptime < 20) {
+ uptime = client.getServerStatus(testServerId).getUptime();
+ }
+
+ assertTrue(uptime > 19);
+
+ client.rebootServer(testServerId);
+
+ Thread.sleep(1000);
- assertTrue(runningServerCounter.apply(ServerState.STOPPED));
- assertTrue(runningServerCounter.apply(ServerState.RUNNING));
+ uptime = client.getServerStatus(testServerId).getUptime();
+
+ assertTrue(uptime < 20);
+
+ assertTrue(serverStatusChecker.apply(ServerState.RUNNING));
}
- @Test(dependsOnMethods = "testCreateServer")
+ @Test(enabled=false) // TODO
public void testStopAndStartServer() throws Exception {
- client.stopServer(testServer.getId());
+ client.stopServer(testServerId);
- assertTrue(runningServerCounter.apply(ServerState.STOPPED));
+ assertTrue(serverStatusChecker.apply(ServerState.STOPPED));
- client.startServer(testServer.getId());
+ client.startServer(testServerId);
- assertTrue(runningServerCounter.apply(ServerState.RUNNING));
+ assertTrue(serverStatusChecker.apply(ServerState.RUNNING));
}
- @Test(dependsOnMethods = "testCreateServer")
+ @Test
public void testServerLimits() throws Exception {
- Map<String, ServerLimit> limits = client.getServerLimits(testServer.getId());
+ Map<String, ServerLimit> limits = client.getServerLimits(testServerId);
assertNotNull(limits);
for (Map.Entry<String, ServerLimit> entry : limits.entrySet()) {
assertNotNull(entry.getKey());
@@ -183,27 +193,27 @@
}
}
- // TODO in progress
- @Test(enabled=false, dependsOnMethods = "testCreateServer")
+ @Test
public void testServerConsole() throws Exception {
- ServerConsole console = client.getServerConsole(testServer.getId());
+ ServerConsole console = client.getServerConsole(testServerId);
assertNotNull(console);
assertNotNull(console.getHost());
assertTrue(console.getPort() > 0 && console.getPort() < 65537);
assertNotNull(console.getPassword());
}
- // takes a few minutes
- @Test(enabled=false, dependsOnMethods = "testCreateServer")
+ // takes a few minutes and requires an extra server (using 2 already)
+ @Test(enabled=false)
public void testCloneServer() throws Exception {
- testServer2 = client.cloneServer(testServer.getId(), "jclouds-test2", ServerCloneOptions.Builder.cpucores(1));
+ ServerCreated testServer2 = client.cloneServer(testServerId, testHostName2, ServerCloneOptions.Builder.cpucores(1));
assertNotNull(testServer2.getId());
assertEquals(testServer2.getHostname(), "jclouds-test2");
assertTrue(testServer2.getIps().isEmpty());
+
+ testServerId2 = testServer2.getId();
- RetryablePredicate<ServerState> cloneChecker = new ServerStatusChecker(testServer2.getId(), 300, 10, TimeUnit.SECONDS);
-
+ RetryablePredicate<ServerState> cloneChecker = new ServerStatusChecker(client, testServerId2, 300, 10, TimeUnit.SECONDS);
assertTrue(cloneChecker.apply(ServerState.STOPPED));
client.startServer(testServer2.getId());
@@ -213,12 +223,12 @@
new Predicate<ServerState>() {
public boolean apply(ServerState value) {
- ServerStatus status = client.getServerStatus(testServer2.getId(), ServerStatusOptions.Builder.state());
+ ServerStatus status = client.getServerStatus(testServerId2, ServerStatusOptions.Builder.state());
if (status.getState() == value) {
return true;
}
-
- client.startServer(testServer2.getId());
+
+ client.startServer(testServerId2);
return false;
}
@@ -265,17 +275,4 @@
assert status.getMemory().getUsage() >= 0 : status;
assertNotNull(status.getMemory().getUnit());
}
-
- private class ServerStatusChecker extends RetryablePredicate<ServerState> {
- public ServerStatusChecker(final String serverId, long maxWait, long period, TimeUnit unit) {
- super(new Predicate<ServerState>() {
-
- public boolean apply(ServerState value) {
- ServerStatus status = client.getServerStatus(serverId, ServerStatusOptions.Builder.state());
- return status.getState() == value;
- }
-
- }, maxWait, period, unit);
- }
- }
}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveAllowedArgumentsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveAllowedArgumentsTest.java
index d42147b..27090a6 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveAllowedArgumentsTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveAllowedArgumentsTest.java
@@ -19,20 +19,18 @@
package org.jclouds.glesys.parse;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
import org.jclouds.glesys.domain.ArchiveAllowedArguments;
-import org.jclouds.glesys.domain.ServerAllowedArguments;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
* @author Adam Lowe
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveDetailsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveDetailsTest.java
index 36f2c1f..250fe8f 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveDetailsTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveDetailsTest.java
@@ -18,22 +18,18 @@
*/
package org.jclouds.glesys.parse;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
-import org.jclouds.glesys.domain.Archive;
import org.jclouds.glesys.domain.ArchiveDetails;
import org.jclouds.json.BaseItemParserTest;
-import org.jclouds.json.BaseParserTest;
-import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import java.util.Set;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
*
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveListTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveListTest.java
index a79e74f..28df00e 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveListTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseArchiveListTest.java
@@ -18,20 +18,21 @@
*/
package org.jclouds.glesys.parse;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
import org.jclouds.glesys.domain.Archive;
-import org.jclouds.glesys.domain.Server;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import java.util.Set;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
*
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainListTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainListTest.java
index 9b49caf..1ff0727 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainListTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainListTest.java
@@ -19,9 +19,16 @@
package org.jclouds.glesys.parse;
-import com.google.common.collect.Sets;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import static org.testng.Assert.fail;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
import org.jclouds.glesys.domain.Domain;
import org.jclouds.json.BaseSetParserTest;
@@ -29,15 +36,9 @@
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Set;
-
-import static org.testng.Assert.fail;
+import com.google.common.collect.Sets;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
* @author Adam Lowe
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainRecordListTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainRecordListTest.java
index 4ecd842..f65de7b 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainRecordListTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseDomainRecordListTest.java
@@ -19,27 +19,22 @@
package org.jclouds.glesys.parse;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Sets;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import java.util.Arrays;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
-import org.jclouds.glesys.domain.Domain;
import org.jclouds.glesys.domain.DomainRecord;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Set;
-
-import static org.testng.Assert.fail;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
* @author Adam Lowe
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailListTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailListTest.java
new file mode 100644
index 0000000..4503371
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailListTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.glesys.parse;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.jclouds.glesys.config.GleSYSParserModule;
+import org.jclouds.glesys.domain.Email;
+import org.jclouds.json.BaseSetParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Set;
+
+/**
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "ParseEmailListTest")
+public class ParseEmailListTest extends BaseSetParserTest<Email> {
+
+ @Override
+ public String resource() {
+ return "/email_list.json";
+ }
+
+ @Override
+ @SelectJson("emailaccounts")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Set<Email> expected() {
+ DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ Email.Builder builder = Email.builder().quota("200 MB").usedQuota("0 MB").antispamLevel(3).antiVirus(true).autoRespond(false).autoRespondSaveEmail(true).autoRespondMessage("false");
+ try {
+ return ImmutableSet.of(
+ builder.account("test@adamlowe.net").created(dateFormat.parse("2011-12-22T12:13:14")).modified(dateFormat.parse("2011-12-22T12:13:35")).build(),
+ builder.account("test2@adamlowe.net").created(dateFormat.parse("2011-12-22T12:14:29")).modified(dateFormat.parse("2011-12-22T12:14:31")).build()
+ );
+ } catch(ParseException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ protected Injector injector() {
+ return Guice.createInjector(new GleSYSParserModule(), new GsonModule());
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailOverviewTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailOverviewTest.java
new file mode 100644
index 0000000..afc53f1
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseEmailOverviewTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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.glesys.parse;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.jclouds.glesys.config.GleSYSParserModule;
+import org.jclouds.glesys.domain.EmailOverview;
+import org.jclouds.glesys.domain.EmailOverviewDomain;
+import org.jclouds.glesys.domain.EmailOverviewSummary;
+import org.jclouds.json.BaseItemParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "ParseEmailListTest")
+public class ParseEmailOverviewTest extends BaseItemParserTest<EmailOverview> {
+
+ @Override
+ public String resource() {
+ return "/email_overview.json";
+ }
+
+ @Override
+ @SelectJson("response")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public EmailOverview expected() {
+ return EmailOverview.builder().summary(EmailOverviewSummary.builder().accounts(2).aliases(0).maxAccounts(50).maxAliases(1000).build()).domains(EmailOverviewDomain.builder().accounts(2).aliases(0).domain("adamlowe.net").build()).build();
+ }
+
+ protected Injector injector() {
+ return Guice.createInjector(new GleSYSParserModule(), new GsonModule());
+ }
+
+}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseIpAddressFromResponseTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseIpAddressFromResponseTest.java
index 9653a64..8284e9c 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseIpAddressFromResponseTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseIpAddressFromResponseTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.glesys.parse;
import com.google.inject.Guice;
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerConsoleTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerConsoleTest.java
new file mode 100644
index 0000000..5e8905b
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerConsoleTest.java
@@ -0,0 +1,56 @@
+/**
+ * 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.glesys.parse;
+
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.glesys.config.GleSYSParserModule;
+import org.jclouds.glesys.domain.ServerConsole;
+import org.jclouds.json.BaseItemParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.SelectJson;
+import org.testng.annotations.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * @author Adam Lowe
+ */
+@Test(groups = "unit", testName = "ParseServerCreatedTest")
+public class ParseServerConsoleTest extends BaseItemParserTest<ServerConsole> {
+
+ @Override
+ public String resource() {
+ return "/server_console.json";
+ }
+
+ @Override
+ @SelectJson("remote")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public ServerConsole expected() {
+ return ServerConsole.builder().host("79.99.2.147").port(59478).password("1476897311").build();
+ }
+
+ protected Injector injector() {
+ return Guice.createInjector(new GleSYSParserModule(), new GsonModule());
+ }
+}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerCreatedTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerCreatedTest.java
index cd1b648..f08739f 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerCreatedTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerCreatedTest.java
@@ -47,7 +47,7 @@
@SelectJson("server")
@Consumes(MediaType.APPLICATION_JSON)
public ServerCreated expected() {
- return ServerCreated.builder().id("xm3630641").hostname("jclouds-test-host").ips(ServerCreatedIp.builder().ip("109.74.10.27").version(4).cost(2.00).build()).build();
+ return ServerCreated.builder().id("xm3630641").hostname("jclouds-test-host").ips(ServerCreatedIp.builder().ip("109.74.10.27").version4().cost(2.00).build()).build();
}
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerStatusTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerStatusTest.java
index e398100..4d1e0f5 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerStatusTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerStatusTest.java
@@ -19,15 +19,14 @@
package org.jclouds.glesys.parse;
-import com.google.inject.Guice;
-import com.google.inject.Injector;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.core.MediaType;
+
import org.jclouds.glesys.config.GleSYSParserModule;
import org.jclouds.glesys.domain.Bandwidth;
-import org.jclouds.glesys.domain.Cost;
import org.jclouds.glesys.domain.Cpu;
import org.jclouds.glesys.domain.Disk;
import org.jclouds.glesys.domain.Memory;
-import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.glesys.domain.ServerState;
import org.jclouds.glesys.domain.ServerStatus;
import org.jclouds.json.BaseItemParserTest;
@@ -35,8 +34,8 @@
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
/**
* @author Adam Lowe
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerTemplatesTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerTemplatesTest.java
index e42f01b..64d0730 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerTemplatesTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseServerTemplatesTest.java
@@ -18,26 +18,29 @@
*/
package org.jclouds.glesys.parse;
+import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
-import java.util.*;
+import org.jclouds.glesys.config.GleSYSParserModule;
+import org.jclouds.glesys.domain.ServerTemplate;
+import org.jclouds.glesys.functions.ParseServerTemplatesFromHttpResponse;
+import org.jclouds.json.BaseSetParserTest;
+import org.jclouds.json.config.GsonModule;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.testng.annotations.Test;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import org.jclouds.glesys.config.GleSYSParserModule;
-import org.jclouds.glesys.domain.*;
-import org.jclouds.json.BaseItemParserTest;
-import org.jclouds.json.config.GsonModule;
-import org.jclouds.rest.annotations.SelectJson;
-import org.testng.annotations.Test;
/**
* @author Adam Lowe
*/
@Test(groups = "unit", testName = "ParseServerTemplatesTest")
-public class ParseServerTemplatesTest extends BaseItemParserTest<Map<String, Set<ServerTemplate>>> {
+public class ParseServerTemplatesTest extends BaseSetParserTest<ServerTemplate> {
@Override
public String resource() {
@@ -45,40 +48,29 @@
}
@Override
- @SelectJson("templates")
+ @ResponseParser(ParseServerTemplatesFromHttpResponse.class)
@Consumes(MediaType.APPLICATION_JSON)
- public Map<String, Set<ServerTemplate>> expected() {
- Map<String, Set<ServerTemplate>> result = new LinkedHashMap<String, Set<ServerTemplate>>();
-
- String[] vzNames = new String[]{
- "Centos 5", "Centos 5 64-bit", "Centos 6 32-bit", "Centos 6 64-bit",
- "Debian 5.0 32-bit", "Debian 5.0 64-bit", "Debian 6.0 32-bit", "Debian 6.0 64-bit",
- "Fedora Core 11", "Fedora Core 11 64-bit", "Gentoo", "Gentoo 64-bit",
- "Scientific Linux 6", "Scientific Linux 6 64-bit", "Slackware 12",
- "Ubuntu 10.04 LTS 32-bit", "Ubuntu 10.04 LTS 64-bit", "Ubuntu 11.04 64-bit"
- };
- String[] xenLinuxNames = new String[] {
- "CentOS 5.5 x64", "CentOS 5.5 x86", "Centos 6 x64", "Centos 6 x86", "Debian-6 x64", "Debian 5.0.1 x64",
- "FreeBSD 8.2", "Gentoo 10.1 x64", "Ubuntu 8.04 x64", "Ubuntu 10.04 LTS 64-bit", "Ubuntu 10.10 x64", "Ubuntu 11.04 x64",
- };
- String[] xenWindowsNames = new String[] {
- "Windows Server 2008 R2 x64 std", "Windows Server 2008 R2 x64 web", "Windows Server 2008 x64 web", "Windows Server 2008 x86 web"
- };
+ public Set<ServerTemplate> expected() {
+ Builder<ServerTemplate> builder = ImmutableSet.<ServerTemplate> builder();
- result.put("OpenVZ", new HashSet<ServerTemplate>());
- for (String name : vzNames) {
- result.get("OpenVZ").add(new ServerTemplate(name, 5, 128, "linux", "OpenVZ"));
+ for (String name : new String[] { "Centos 5", "Centos 5 64-bit", "Centos 6 32-bit", "Centos 6 64-bit",
+ "Debian 5.0 32-bit", "Debian 5.0 64-bit", "Debian 6.0 32-bit", "Debian 6.0 64-bit", "Fedora Core 11",
+ "Fedora Core 11 64-bit", "Gentoo", "Gentoo 64-bit", "Scientific Linux 6", "Scientific Linux 6 64-bit",
+ "Slackware 12", "Ubuntu 10.04 LTS 32-bit", "Ubuntu 10.04 LTS 64-bit", "Ubuntu 11.04 64-bit" }) {
+ builder.add(new ServerTemplate(name, 5, 128, "linux", "OpenVZ"));
}
- result.put("Xen", new HashSet<ServerTemplate>());
- for (String name : xenLinuxNames) {
- result.get("Xen").add(new ServerTemplate(name, 5, 512, name.startsWith("FreeBSD") ? "freebsd" : "linux", "Xen"));
+ for (String name : new String[] { "CentOS 5.5 x64", "CentOS 5.5 x86", "Centos 6 x64", "Centos 6 x86",
+ "Debian-6 x64", "Debian 5.0.1 x64", "FreeBSD 8.2", "Gentoo 10.1 x64", "Ubuntu 8.04 x64",
+ "Ubuntu 10.04 LTS 64-bit", "Ubuntu 10.10 x64", "Ubuntu 11.04 x64" }) {
+ builder.add(new ServerTemplate(name, 5, 512, name.startsWith("FreeBSD") ? "freebsd" : "linux", "Xen"));
}
- for (String name : xenWindowsNames) {
- result.get("Xen").add(new ServerTemplate(name, 20, 1024, "windows", "Xen"));
+ for (String name : new String[] { "Windows Server 2008 R2 x64 std", "Windows Server 2008 R2 x64 web",
+ "Windows Server 2008 x64 web", "Windows Server 2008 x86 web" }) {
+ builder.add(new ServerTemplate(name, 20, 1024, "windows", "Xen"));
}
-
- return result;
+
+ return builder.build();
}
protected Injector injector() {
diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java
index 52c0c98..d7dc291 100644
--- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java
+++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java
@@ -1,4 +1,4 @@
-/*
+/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.jclouds.glesys.parse;
import com.google.inject.Guice;
diff --git a/sandbox-providers/glesys/src/test/resources/email_list.json b/sandbox-providers/glesys/src/test/resources/email_list.json
new file mode 100644
index 0000000..b970ad8
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/resources/email_list.json
@@ -0,0 +1 @@
+{"response":{"status":{"code":"200","text":"OK"},"list":{"emailaccounts":[{"emailaccount":"test2@adamlowe.net","quota":"200 MB","usedquota":"0 MB","antispamlevel":3,"antivirus":true,"autorespond":false,"autorespondmessage":false,"autorespondsaveemail":true,"created":"2011-12-22 12:14:29","modified":"2011-12-22 12:14:31"},{"emailaccount":"test@adamlowe.net","quota":"200 MB","usedquota":"0 MB","antispamlevel":3,"antivirus":true,"autorespond":false,"autorespondmessage":false,"autorespondsaveemail":true,"created":"2011-12-22 12:13:14","modified":"2011-12-22 12:13:35"}]},"debug":{"input":{"domain":"adamlowe.net"}}}}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/test/resources/email_overview.json b/sandbox-providers/glesys/src/test/resources/email_overview.json
new file mode 100644
index 0000000..d98a8c8
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/resources/email_overview.json
@@ -0,0 +1 @@
+{"response":{"status":{"code":"200","text":"OK"},"summary":{"accounts":2,"maxaccounts":"50","aliases":0,"maxaliases":1000},"domains":[{"domain":"adamlowe.net","accounts":2,"aliases":0}],"debug":{"input":[]}}}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/test/resources/ip_release.json b/sandbox-providers/glesys/src/test/resources/ip_release.json
new file mode 100644
index 0000000..1367493
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/resources/ip_release.json
@@ -0,0 +1 @@
+{"response":{"status":{"code":"200","text":"OK"},"debug":{"input":{"ipaddress":"31.192.227.37"}}}}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/test/resources/ip_take.json b/sandbox-providers/glesys/src/test/resources/ip_take.json
new file mode 100644
index 0000000..e0d9e40
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/resources/ip_take.json
@@ -0,0 +1 @@
+{"response":{"status":{"code":"200","text":"OK"},"debug":{"input":{"ipaddress":"46.21.105.186"}}}}
\ No newline at end of file
diff --git a/sandbox-providers/glesys/src/test/resources/server_console.json b/sandbox-providers/glesys/src/test/resources/server_console.json
new file mode 100644
index 0000000..ae49ef9
--- /dev/null
+++ b/sandbox-providers/glesys/src/test/resources/server_console.json
@@ -0,0 +1 @@
+{"response":{"status":{"code":"200","text":"OK"},"remote":{"host":"79.99.2.147","port":"59478","password":"1476897311"},"debug":{"input":{"serverid":"vz1842554"}}}}
\ No newline at end of file
diff --git a/sandbox-providers/googlestorage/pom.xml b/sandbox-providers/googlestorage/pom.xml
index 57bc2e7..c42aab0 100644
--- a/sandbox-providers/googlestorage/pom.xml
+++ b/sandbox-providers/googlestorage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.googlestorage.blobstore.GoogleStorageTestInitializer</test.initializer>
<test.googlestorage.endpoint>https://commondatastorage.googleapis.com</test.googlestorage.endpoint>
- <test.googlestorage.apiversion>2006-03-01</test.googlestorage.apiversion>
+ <test.googlestorage.api-version>2006-03-01</test.googlestorage.api-version>
+ <test.googlestorage.build-version></test.googlestorage.build-version>
<test.googlestorage.identity>FIX_ME</test.googlestorage.identity>
<test.googlestorage.credential>FIX_ME</test.googlestorage.credential>
</properties>
@@ -101,7 +102,8 @@
<configuration>
<systemPropertyVariables>
<test.googlestorage.endpoint>${test.googlestorage.endpoint}</test.googlestorage.endpoint>
- <test.googlestorage.apiversion>${test.googlestorage.apiversion}</test.googlestorage.apiversion>
+ <test.googlestorage.api-version>${test.googlestorage.api-version}</test.googlestorage.api-version>
+ <test.googlestorage.build-version>${test.googlestorage.build-version}</test.googlestorage.build-version>
<test.googlestorage.identity>${test.googlestorage.identity}</test.googlestorage.identity>
<test.googlestorage.credential>${test.googlestorage.credential}</test.googlestorage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/sandbox-providers/hosteurope-storage/pom.xml b/sandbox-providers/hosteurope-storage/pom.xml
index 6c01b63..2b51626 100644
--- a/sandbox-providers/hosteurope-storage/pom.xml
+++ b/sandbox-providers/hosteurope-storage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.hosteurope.storage.blobstore.HostEuropeStorageTestInitializer</test.initializer>
<test.hosteurope-storage.endpoint>https://cs.hosteurope.de</test.hosteurope-storage.endpoint>
- <test.hosteurope-storage.apiversion>2006-03-01</test.hosteurope-storage.apiversion>
+ <test.hosteurope-storage.api-version>2006-03-01</test.hosteurope-storage.api-version>
+ <test.hosteurope-storage.build-version></test.hosteurope-storage.build-version>
<test.hosteurope-storage.identity>FIX_ME</test.hosteurope-storage.identity>
<test.hosteurope-storage.credential>FIX_ME</test.hosteurope-storage.credential>
</properties>
@@ -108,7 +109,8 @@
<configuration>
<systemPropertyVariables>
<test.hosteurope-storage.endpoint>${test.hosteurope-storage.endpoint}</test.hosteurope-storage.endpoint>
- <test.hosteurope-storage.apiversion>${test.hosteurope-storage.apiversion}</test.hosteurope-storage.apiversion>
+ <test.hosteurope-storage.api-version>${test.hosteurope-storage.api-version}</test.hosteurope-storage.api-version>
+ <test.hosteurope-storage.build-version>${test.hosteurope-storage.build-version}</test.hosteurope-storage.build-version>
<test.hosteurope-storage.identity>${test.hosteurope-storage.identity}</test.hosteurope-storage.identity>
<test.hosteurope-storage.credential>${test.hosteurope-storage.credential}</test.hosteurope-storage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/sandbox-providers/ibm-smartcloud/pom.xml b/sandbox-providers/ibm-smartcloud/pom.xml
index 08f70f0..c8ea4dd 100644
--- a/sandbox-providers/ibm-smartcloud/pom.xml
+++ b/sandbox-providers/ibm-smartcloud/pom.xml
@@ -49,7 +49,8 @@
<properties>
<test.ibm-smartcloud.endpoint>https://www-147.ibm.com/computecloud/enterprise/api/rest</test.ibm-smartcloud.endpoint>
- <test.ibm-smartcloud.apiversion>20100331</test.ibm-smartcloud.apiversion>
+ <test.ibm-smartcloud.api-version>20100331</test.ibm-smartcloud.api-version>
+ <test.ibm-smartcloud.build-version></test.ibm-smartcloud.build-version>
<test.ibm-smartcloud.identity>FIXME</test.ibm-smartcloud.identity>
<test.ibm-smartcloud.credential>FIXME</test.ibm-smartcloud.credential>
<test.ibm-smartcloud.image-id></test.ibm-smartcloud.image-id>
@@ -110,7 +111,8 @@
<configuration>
<systemPropertyVariables>
<test.ibm-smartcloud.endpoint>${test.ibm-smartcloud.endpoint}</test.ibm-smartcloud.endpoint>
- <test.ibm-smartcloud.apiversion>${test.ibm-smartcloud.apiversion}</test.ibm-smartcloud.apiversion>
+ <test.ibm-smartcloud.api-version>${test.ibm-smartcloud.api-version}</test.ibm-smartcloud.api-version>
+ <test.ibm-smartcloud.build-version>${test.ibm-smartcloud.build-version}</test.ibm-smartcloud.build-version>
<test.ibm-smartcloud.identity>${test.ibm-smartcloud.identity}</test.ibm-smartcloud.identity>
<test.ibm-smartcloud.credential>${test.ibm-smartcloud.credential}</test.ibm-smartcloud.credential>
<test.ibm-smartcloud.image-id>${test.ibm-smartcloud.image-id}</test.ibm-smartcloud.image-id>
diff --git a/sandbox-providers/ibm-smartcloud/src/test/java/org/jclouds/ibm/smartcloud/BaseIBMSmartCloudClientLiveTest.java b/sandbox-providers/ibm-smartcloud/src/test/java/org/jclouds/ibm/smartcloud/BaseIBMSmartCloudClientLiveTest.java
index 736bf85..b755e69 100644
--- a/sandbox-providers/ibm-smartcloud/src/test/java/org/jclouds/ibm/smartcloud/BaseIBMSmartCloudClientLiveTest.java
+++ b/sandbox-providers/ibm-smartcloud/src/test/java/org/jclouds/ibm/smartcloud/BaseIBMSmartCloudClientLiveTest.java
@@ -49,7 +49,7 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected IBMSmartCloudClient connection;
@@ -61,7 +61,7 @@
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential must be set. ex. secretKey");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -72,8 +72,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-providers/scaleup-storage/pom.xml b/sandbox-providers/scaleup-storage/pom.xml
index cc711d8..9840623 100644
--- a/sandbox-providers/scaleup-storage/pom.xml
+++ b/sandbox-providers/scaleup-storage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.scaleup.storage.blobstore.ScaleUpStorageTestInitializer</test.initializer>
<test.scaleup-storage.endpoint>https://scs.scaleupstorage.com</test.scaleup-storage.endpoint>
- <test.scaleup-storage.apiversion>2006-03-01</test.scaleup-storage.apiversion>
+ <test.scaleup-storage.api-version>2006-03-01</test.scaleup-storage.api-version>
+ <test.scaleup-storage.build-version></test.scaleup-storage.build-version>
<test.scaleup-storage.identity>FIX_ME</test.scaleup-storage.identity>
<test.scaleup-storage.credential>FIX_ME</test.scaleup-storage.credential>
</properties>
@@ -108,7 +109,8 @@
<configuration>
<systemPropertyVariables>
<test.scaleup-storage.endpoint>${test.scaleup-storage.endpoint}</test.scaleup-storage.endpoint>
- <test.scaleup-storage.apiversion>${test.scaleup-storage.apiversion}</test.scaleup-storage.apiversion>
+ <test.scaleup-storage.api-version>${test.scaleup-storage.api-version}</test.scaleup-storage.api-version>
+ <test.scaleup-storage.build-version>${test.scaleup-storage.build-version}</test.scaleup-storage.build-version>
<test.scaleup-storage.identity>${test.scaleup-storage.identity}</test.scaleup-storage.identity>
<test.scaleup-storage.credential>${test.scaleup-storage.credential}</test.scaleup-storage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/sandbox-providers/tiscali-storage/pom.xml b/sandbox-providers/tiscali-storage/pom.xml
index 90da860..2deac1f 100644
--- a/sandbox-providers/tiscali-storage/pom.xml
+++ b/sandbox-providers/tiscali-storage/pom.xml
@@ -36,7 +36,8 @@
<properties>
<test.initializer>org.jclouds.tiscali.storage.blobstore.TiscaliStorageTestInitializer</test.initializer>
<test.tiscali-storage.endpoint>https://storage.tiscali.it</test.tiscali-storage.endpoint>
- <test.tiscali-storage.apiversion>2006-03-01</test.tiscali-storage.apiversion>
+ <test.tiscali-storage.api-version>2006-03-01</test.tiscali-storage.api-version>
+ <test.tiscali-storage.build-version></test.tiscali-storage.build-version>
<test.tiscali-storage.identity>FIX_ME</test.tiscali-storage.identity>
<test.tiscali-storage.credential>FIX_ME</test.tiscali-storage.credential>
</properties>
@@ -109,7 +110,8 @@
<threadCount>1</threadCount>
<systemPropertyVariables>
<test.tiscali-storage.endpoint>${test.tiscali-storage.endpoint}</test.tiscali-storage.endpoint>
- <test.tiscali-storage.apiversion>${test.tiscali-storage.apiversion}</test.tiscali-storage.apiversion>
+ <test.tiscali-storage.api-version>${test.tiscali-storage.api-version}</test.tiscali-storage.api-version>
+ <test.tiscali-storage.build-version>${test.tiscali-storage.build-version}</test.tiscali-storage.build-version>
<test.tiscali-storage.identity>${test.tiscali-storage.identity}</test.tiscali-storage.identity>
<test.tiscali-storage.credential>${test.tiscali-storage.credential}</test.tiscali-storage.credential>
<test.initializer>${test.initializer}</test.initializer>
diff --git a/sandbox-providers/twitter/pom.xml b/sandbox-providers/twitter/pom.xml
index b17df97..cdfcb46 100644
--- a/sandbox-providers/twitter/pom.xml
+++ b/sandbox-providers/twitter/pom.xml
@@ -50,7 +50,8 @@
<properties>
<!-- when instances are hung, open a ticket and add here -->
<test.twitter.endpoint>http://api.twitter.com</test.twitter.endpoint>
- <test.twitter.apiversion>1.0</test.twitter.apiversion>
+ <test.twitter.api-version>1.0</test.twitter.api-version>
+ <test.twitter.build-version></test.twitter.build-version>
<test.twitter.identity>FIXME</test.twitter.identity>
<test.twitter.credential>FIXME</test.twitter.credential>
</properties>
@@ -98,7 +99,8 @@
<configuration>
<systemPropertyVariables>
<test.twitter.endpoint>${test.twitter.endpoint}</test.twitter.endpoint>
- <test.twitter.apiversion>${test.twitter.apiversion}</test.twitter.apiversion>
+ <test.twitter.api-version>${test.twitter.api-version}</test.twitter.api-version>
+ <test.twitter.build-version>${test.twitter.build-version}</test.twitter.build-version>
<test.twitter.identity>${test.twitter.identity}</test.twitter.identity>
<test.twitter.credential>${test.twitter.credential}</test.twitter.credential>
</systemPropertyVariables>
diff --git a/sandbox-providers/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java b/sandbox-providers/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java
index 30ef89b..0ac3cf8 100644
--- a/sandbox-providers/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java
+++ b/sandbox-providers/twitter/src/test/java/org/jclouds/twitter/TwitterClientLiveTest.java
@@ -51,13 +51,13 @@
protected String identity;
protected String credential;
protected String endpoint;
- protected String apiversion;
+ protected String apiVersion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = System.getProperty("test." + provider + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+ apiVersion = System.getProperty("test." + provider + ".api-version");
}
protected Properties setupProperties() {
@@ -69,8 +69,8 @@
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
- if (apiversion != null)
- overrides.setProperty(provider + ".apiversion", apiversion);
+ if (apiVersion != null)
+ overrides.setProperty(provider + ".api-version", apiVersion);
return overrides;
}
diff --git a/sandbox-providers/virtacore-vcloudexpress/pom.xml b/sandbox-providers/virtacore-vcloudexpress/pom.xml
index 37b4df5..a2a0d29 100644
--- a/sandbox-providers/virtacore-vcloudexpress/pom.xml
+++ b/sandbox-providers/virtacore-vcloudexpress/pom.xml
@@ -34,7 +34,8 @@
<properties>
<test.virtacore-vcloudexpress.endpoint>https://vcloud.virtacore.com/api</test.virtacore-vcloudexpress.endpoint>
- <test.virtacore-vcloudexpress.apiversion>1.0</test.virtacore-vcloudexpress.apiversion>
+ <test.virtacore-vcloudexpress.api-version>1.0</test.virtacore-vcloudexpress.api-version>
+ <test.virtacore-vcloudexpress.build-version></test.virtacore-vcloudexpress.build-version>
<test.virtacore-vcloudexpress.identity>FIXME_IDENTITY</test.virtacore-vcloudexpress.identity>
<test.virtacore-vcloudexpress.credential>FIXME_CREDENTIAL</test.virtacore-vcloudexpress.credential>
<test.virtacore-vcloudexpress.image-id></test.virtacore-vcloudexpress.image-id>
@@ -99,7 +100,8 @@
<configuration>
<systemPropertyVariables>
<test.virtacore-vcloudexpress.endpoint>${test.virtacore-vcloudexpress.endpoint}</test.virtacore-vcloudexpress.endpoint>
- <test.virtacore-vcloudexpress.apiversion>${test.virtacore-vcloudexpress.apiversion}</test.virtacore-vcloudexpress.apiversion>
+ <test.virtacore-vcloudexpress.api-version>${test.virtacore-vcloudexpress.api-version}</test.virtacore-vcloudexpress.api-version>
+ <test.virtacore-vcloudexpress.build-version>${test.virtacore-vcloudexpress.build-version}</test.virtacore-vcloudexpress.build-version>
<test.virtacore-vcloudexpress.identity>${test.virtacore-vcloudexpress.identity}</test.virtacore-vcloudexpress.identity>
<test.virtacore-vcloudexpress.credential>${test.virtacore-vcloudexpress.credential}</test.virtacore-vcloudexpress.credential>
<test.virtacore-vcloudexpress.image-id>${test.virtacore-vcloudexpress.image-id}</test.virtacore-vcloudexpress.image-id>
diff --git a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java b/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java
deleted file mode 100644
index e9d42c8..0000000
--- a/scriptbuilder/src/main/java/org/jclouds/scriptbuilder/domain/AuthorizeRSAPublicKey.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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.scriptbuilder.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
-
-import com.google.common.collect.ImmutableSet;
-
-/**
- *
- * @author Adrian Cole
- * @see AuthorizeRSAPublicKeys
- */
-@Deprecated
-public class AuthorizeRSAPublicKey extends AuthorizeRSAPublicKeys {
-
- public AuthorizeRSAPublicKey(String publicKey) {
- super(ImmutableSet.of(checkNotNull(publicKey, "publicKey")));
- }
-
-}
\ No newline at end of file
diff --git a/skeletons/standalone-compute/pom.xml b/skeletons/standalone-compute/pom.xml
index c416987..e3dd9b9 100644
--- a/skeletons/standalone-compute/pom.xml
+++ b/skeletons/standalone-compute/pom.xml
@@ -37,7 +37,8 @@
<jclouds.compute.blacklist-nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist-nodes>
<test.servermanager.identity>FIXME</test.servermanager.identity>
<test.servermanager.endpoint>https://servermanager.com</test.servermanager.endpoint>
- <test.servermanager.apiversion>1.0</test.servermanager.apiversion>
+ <test.servermanager.api-version>1.0</test.servermanager.api-version>
+ <test.servermanager.build-version></test.servermanager.build-version>
<test.servermanager.identity>FIXME</test.servermanager.identity>
</properties>
<dependencies>
@@ -98,7 +99,8 @@
<configuration>
<systemPropertyVariables>
<test.servermanager.endpoint>${test.servermanager.endpoint}</test.servermanager.endpoint>
- <test.servermanager.apiversion>${test.servermanager.apiversion}</test.servermanager.apiversion>
+ <test.servermanager.api-version>${test.servermanager.api-version}</test.servermanager.api-version>
+ <test.servermanager.build-version>${test.servermanager.build-version}</test.servermanager.build-version>
<test.servermanager.identity>${test.servermanager.identity}</test.servermanager.identity>
<jclouds.compute.blacklist-nodes>${jclouds.compute.blacklist-nodes}</jclouds.compute.blacklist-nodes>
</systemPropertyVariables>
diff --git a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceContextBuilderTest.java b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceContextBuilderTest.java
index 3aea091..9992f1a 100644
--- a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceContextBuilderTest.java
+++ b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceContextBuilderTest.java
@@ -55,7 +55,7 @@
public void testCanBuildWithContextSpec() {
ComputeServiceContext context = new ComputeServiceContextFactory()
.createContext(new StandaloneComputeServiceContextSpec<ServerManager, Server, Hardware, Image, Datacenter>(
- "servermanager", "http://host", "1", "", "identity", "credential", ServerManager.class,
+ "servermanager", "http://host", "1", "", "", "identity", "credential", ServerManager.class,
ServerManagerComputeServiceContextBuilder.class, ImmutableSet.<Module> of()));
context.close();
@@ -67,7 +67,7 @@
restProperties.setProperty("servermanager.contextbuilder", ServerManagerComputeServiceContextBuilder.class
.getName());
restProperties.setProperty("servermanager.endpoint", "http://host");
- restProperties.setProperty("servermanager.apiversion", "1");
+ restProperties.setProperty("servermanager.api-version", "1");
ComputeServiceContext context = new ComputeServiceContextFactory(restProperties).createContext("servermanager",
"identity", "credential");
diff --git a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceLiveTest.java b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceLiveTest.java
index 51c5278..7844e19 100644
--- a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceLiveTest.java
+++ b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerComputeServiceLiveTest.java
@@ -50,7 +50,7 @@
restProperties.setProperty("servermanager.contextbuilder",
ServerManagerComputeServiceContextBuilder.class.getName());
restProperties.setProperty("servermanager.endpoint", "http://host");
- restProperties.setProperty("servermanager.apiversion", "1");
+ restProperties.setProperty("servermanager.api-version", "1");
return restProperties;
}
diff --git a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerExperimentLiveTest.java b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerExperimentLiveTest.java
index e0753bb..aa547e9 100644
--- a/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerExperimentLiveTest.java
+++ b/skeletons/standalone-compute/src/test/java/org/jclouds/servermanager/compute/ServerManagerExperimentLiveTest.java
@@ -18,8 +18,7 @@
*/
package org.jclouds.servermanager.compute;
-import static com.google.common.base.Preconditions.checkNotNull;
-
+import org.jclouds.compute.BaseVersionedServiceLiveTest;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.StandaloneComputeServiceContextSpec;
@@ -28,7 +27,6 @@
import org.jclouds.servermanager.Image;
import org.jclouds.servermanager.Server;
import org.jclouds.servermanager.ServerManager;
-import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@@ -38,29 +36,19 @@
*
* @author Adrian Cole
*/
-@Test(groups = "live")
-public class ServerManagerExperimentLiveTest {
- protected String provider = "servermanager";
- protected String identity;
- protected String credential;
- protected String endpoint;
- protected String apiversion;
-
- @BeforeClass
- protected void setupCredentials() {
- identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
- credential = System.getProperty("test." + provider + ".credential");
- endpoint = System.getProperty("test." + provider + ".endpoint");
- apiversion = System.getProperty("test." + provider + ".apiversion");
+@Test(groups = "live", singleThreaded = true, testName = "ServerManagerExperimentLiveTest")
+public class ServerManagerExperimentLiveTest extends BaseVersionedServiceLiveTest {
+ public ServerManagerExperimentLiveTest() {
+ provider = "servermanager";
}
-
+
@Test
public void testAndExperiment() {
ComputeServiceContext context = null;
try {
context = new ComputeServiceContextFactory()
.createContext(new StandaloneComputeServiceContextSpec<ServerManager, Server, Hardware, Image, Datacenter>(
- "servermanager", endpoint, apiversion, "", identity, credential, ServerManager.class,
+ "servermanager", endpoint, apiVersion, buildVersion, "", identity, credential, ServerManager.class,
ServerManagerComputeServiceContextBuilder.class, ImmutableSet.<Module> of()));
context.getComputeService().listNodes();
@@ -71,4 +59,4 @@
}
}
-}
\ No newline at end of file
+}