Issue 798: merge for potential 1.3.0-rc-2

This commit is contained in:
Adrian Cole 2012-01-10 18:21:41 -08:00
commit f368485acd
507 changed files with 12608 additions and 4613 deletions

View File

@ -36,7 +36,8 @@
<properties> <properties>
<test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer> <test.initializer>org.jclouds.atmos.blobstore.integration.AtmosStorageTestInitializer</test.initializer>
<test.atmos.endpoint>https://accesspoint.atmos.com</test.atmos.endpoint> <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.identity>FIXME</test.atmos.identity>
<test.atmos.credential>FIXME</test.atmos.credential> <test.atmos.credential>FIXME</test.atmos.credential>
</properties> </properties>
@ -95,7 +96,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url> <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5> <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.atmos.endpoint>${test.atmos.endpoint}</test.atmos.endpoint> <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.identity>${test.atmos.identity}</test.atmos.identity>
<test.atmos.credential>${test.atmos.credential}</test.atmos.credential> <test.atmos.credential>${test.atmos.credential}</test.atmos.credential>
</systemPropertyVariables> </systemPropertyVariables>

View File

@ -38,10 +38,10 @@ public class AtmosTestInitializer extends TransientBlobStoreTestInitializer {
} }
@Override @Override
protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion, protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiVersion,
String app, String identity, String credential) throws IOException { String buildVersion, String app, String identity, String credential) throws IOException {
return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule, return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule,
new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential)); new Log4JLoggingModule()), setupProperties(endpoint, apiVersion, buildVersion, identity, credential));
} }
} }

View File

@ -35,9 +35,9 @@ import org.yaml.snakeyaml.constructor.Constructor;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Functions; import com.google.common.base.Functions;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;

View File

@ -36,7 +36,8 @@
<properties> <properties>
<test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer> <test.initializer>org.jclouds.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
<test.cloudfiles.endpoint>https://auth.api.rackspacecloud.com</test.cloudfiles.endpoint> <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.identity>${test.rackspace.identity}</test.cloudfiles.identity>
<test.cloudfiles.credential>${test.rackspace.credential}</test.cloudfiles.credential> <test.cloudfiles.credential>${test.rackspace.credential}</test.cloudfiles.credential>
</properties> </properties>
@ -110,7 +111,8 @@
<jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url> <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5> <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
<test.cloudfiles.endpoint>${test.cloudfiles.endpoint}</test.cloudfiles.endpoint> <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.identity>${test.cloudfiles.identity}</test.cloudfiles.identity>
<test.cloudfiles.credential>${test.cloudfiles.credential}</test.cloudfiles.credential> <test.cloudfiles.credential>${test.cloudfiles.credential}</test.cloudfiles.credential>
</systemPropertyVariables> </systemPropertyVariables>

View File

@ -52,6 +52,9 @@ public class PublicUriForObjectInfo implements Function<ObjectInfo, URI> {
try { try {
return uriBuilders.get().uri(cdnContainer.getUnchecked(from.getContainer())).path(from.getName()).replaceQuery("") return uriBuilders.get().uri(cdnContainer.getUnchecked(from.getContainer())).path(from.getName()).replaceQuery("")
.build(); .build();
} catch (NullPointerException e) {
// nulls not permitted from cache loader
return null;
} catch (CacheLoader.InvalidCacheLoadException e) { } catch (CacheLoader.InvalidCacheLoadException e) {
// nulls not permitted from cache loader // nulls not permitted from cache loader
return null; return null;

View File

@ -35,7 +35,8 @@
<properties> <properties>
<test.cloudloadbalancers.endpoint>https://auth.api.rackspacecloud.com</test.cloudloadbalancers.endpoint> <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.identity>${test.rackspace.identity}</test.cloudloadbalancers.identity>
<test.cloudloadbalancers.credential>${test.rackspace.credential}</test.cloudloadbalancers.credential> <test.cloudloadbalancers.credential>${test.rackspace.credential}</test.cloudloadbalancers.credential>
</properties> </properties>
@ -96,7 +97,8 @@
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<test.cloudloadbalancers.endpoint>${test.cloudloadbalancers.endpoint}</test.cloudloadbalancers.endpoint> <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.identity>${test.cloudloadbalancers.identity}</test.cloudloadbalancers.identity>
<test.cloudloadbalancers.credential>${test.cloudloadbalancers.credential}</test.cloudloadbalancers.credential> <test.cloudloadbalancers.credential>${test.cloudloadbalancers.credential}</test.cloudloadbalancers.credential>
</systemPropertyVariables> </systemPropertyVariables>

View File

@ -38,6 +38,7 @@ import org.jclouds.cloudloadbalancers.functions.ConvertLB;
import org.jclouds.cloudloadbalancers.handlers.ParseCloudLoadBalancersErrorFromHttpResponse; import org.jclouds.cloudloadbalancers.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
import org.jclouds.cloudloadbalancers.reference.RackspaceConstants; import org.jclouds.cloudloadbalancers.reference.RackspaceConstants;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
@ -51,6 +52,7 @@ import org.jclouds.location.config.ProvideRegionToURIViaProperties;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule; import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders; import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
@ -154,4 +156,8 @@ public class CloudLoadBalancersRestClientModule extends
ParseCloudLoadBalancersErrorFromHttpResponse.class); ParseCloudLoadBalancersErrorFromHttpResponse.class);
} }
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
}
} }

View File

@ -18,17 +18,19 @@
*/ */
package org.jclouds.cloudloadbalancers.loadbalancer.functions; package org.jclouds.cloudloadbalancers.loadbalancer.functions;
import java.util.Map; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer; import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
import org.jclouds.cloudloadbalancers.domain.VirtualIP; import org.jclouds.cloudloadbalancers.domain.VirtualIP;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerType; import org.jclouds.loadbalancer.domain.LoadBalancerType;
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl; import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
import org.jclouds.location.predicates.LocationPredicates;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -41,20 +43,20 @@ import com.google.common.collect.Iterables;
*/ */
@Singleton @Singleton
public class LoadBalancerToLoadBalancerMetadata implements Function<LoadBalancer, LoadBalancerMetadata> { 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; protected final Supplier<Location> defaultLocationSupplier;
@Inject @Inject
public LoadBalancerToLoadBalancerMetadata(Supplier<Location> defaultLocationSupplier, public LoadBalancerToLoadBalancerMetadata(Supplier<Location> defaultLocationSupplier,
Supplier<Map<String, ? extends Location>> locationMap) { @Memoized Supplier<Set<? extends Location>> locations) {
this.locationMap = locationMap; this.locations = locations;
this.defaultLocationSupplier = defaultLocationSupplier; this.defaultLocationSupplier = defaultLocationSupplier;
} }
@Override @Override
public LoadBalancerMetadata apply(LoadBalancer input) { 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(); String id = input.getRegion() + "/" + input.getId();
// TODO Builder // TODO Builder

View File

@ -19,6 +19,11 @@
package org.jclouds.cloudloadbalancers; package org.jclouds.cloudloadbalancers;
import static org.jclouds.Constants.PROPERTY_API_VERSION; 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 static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.io.IOException; import java.io.IOException;
@ -84,9 +89,12 @@ public class CloudLoadBalancersAsyncClientTest extends BaseCloudLoadBalancersAsy
@Override @Override
protected Properties getProperties() { protected Properties getProperties() {
Properties overrides = new Properties(); 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(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()); overrides.setProperty(provider + ".contextbuilder", CloudLoadBalancersContextBuilder.class.getName());
return overrides; return overrides;
} }

View File

@ -28,22 +28,34 @@ import java.util.Properties;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.config.CloudLoadBalancersRestClientModule; import org.jclouds.cloudloadbalancers.config.CloudLoadBalancersRestClientModule;
import org.jclouds.cloudloadbalancers.functions.ConvertLB;
import org.jclouds.cloudloadbalancers.reference.Region; import org.jclouds.cloudloadbalancers.reference.Region;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.internal.ClassMethodArgs; 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.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec; import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.internal.RestContextImpl;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.Module; 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 * @author Adrian Cole
@ -58,11 +70,42 @@ public abstract class BaseCloudLoadBalancersAsyncClientTest<T> extends RestClien
bindRegionsToProvider(Regions.class); 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>> { static class Regions implements javax.inject.Provider<Map<String, URI>> {
@Override @Override
public Map<String, URI> get() { public Map<String, URI> get() {
return ImmutableMap.<String, URI> of("DFW", return ImmutableMap.<String, URI> of("DFW", URI
URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234")); .create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234"));
} }
} }

View File

@ -18,12 +18,9 @@
*/ */
package org.jclouds.cloudloadbalancers.features; package org.jclouds.cloudloadbalancers.features;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.Constants;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersAsyncClient;
import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient; import org.jclouds.cloudloadbalancers.CloudLoadBalancersClient;
import org.jclouds.cloudloadbalancers.domain.LoadBalancer; import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
@ -33,6 +30,7 @@ import org.jclouds.loadbalancer.LoadBalancerServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.BaseRestClientLiveTest;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
@ -47,44 +45,20 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BaseCloudLoadBalancersClientLiveTest { public class BaseCloudLoadBalancersClientLiveTest extends BaseRestClientLiveTest {
protected String prefix = System.getProperty("user.name"); public BaseCloudLoadBalancersClientLiveTest() {
provider = "cloudloadbalancers";
}
protected CloudLoadBalancersClient client; protected CloudLoadBalancersClient client;
protected RestContext<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> context; protected RestContext<CloudLoadBalancersClient, CloudLoadBalancersAsyncClient> context;
protected String provider = "cloudloadbalancers";
protected String[] regions = {}; protected String[] regions = {};
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
protected Predicate<IPSocket> socketTester; protected Predicate<IPSocket> socketTester;
protected RetryablePredicate<LoadBalancer> loadBalancerActive; protected RetryablePredicate<LoadBalancer> loadBalancerActive;
protected RetryablePredicate<LoadBalancer> loadBalancerDeleted; protected RetryablePredicate<LoadBalancer> loadBalancerDeleted;
protected Injector injector; 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") @BeforeGroups(groups = "live")
public void setupClient() { public void setupClient() {

View File

@ -36,7 +36,8 @@
<properties> <properties>
<test.cloudservers.endpoint>https://auth.api.rackspacecloud.com</test.cloudservers.endpoint> <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.identity>${test.rackspace.identity}</test.cloudservers.identity>
<test.cloudservers.credential>${test.rackspace.credential}</test.cloudservers.credential> <test.cloudservers.credential>${test.rackspace.credential}</test.cloudservers.credential>
<test.cloudservers.image-id /> <test.cloudservers.image-id />
@ -108,7 +109,8 @@
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<test.cloudstack.endpoint>${test.cloudstack.endpoint}</test.cloudstack.endpoint> <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.identity>${test.cloudstack.identity}</test.cloudstack.identity>
<test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential> <test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential>
<test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id> <test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id>

View File

@ -27,6 +27,7 @@ import org.jclouds.cloudservers.CloudServersClient;
import org.jclouds.cloudservers.ServerManagement; import org.jclouds.cloudservers.ServerManagement;
import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse; import org.jclouds.cloudservers.handlers.ParseCloudServersErrorFromHttpResponse;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.Redirection;
@ -35,6 +36,7 @@ import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
import org.jclouds.openstack.config.OpenStackAuthenticationModule; import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.handlers.RetryOnRenew;
import org.jclouds.openstack.reference.AuthHeaders; import org.jclouds.openstack.reference.AuthHeaders;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
@ -74,6 +76,11 @@ public class CloudServersRestClientModule extends RestClientModule<CloudServersC
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseCloudServersErrorFromHttpResponse.class); bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseCloudServersErrorFromHttpResponse.class);
} }
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
}
@Provides @Provides
@Singleton @Singleton
@ServerManagement @ServerManagement

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}

View File

@ -35,12 +35,13 @@
<properties> <properties>
<test.cloudsigma.endpoint>https://api.cloudsigma.com</test.cloudsigma.endpoint> <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.identity>FIXME</test.cloudsigma.identity>
<test.cloudsigma.credential>FIXME</test.cloudsigma.credential> <test.cloudsigma.credential>FIXME</test.cloudsigma.credential>
<test.cloudsigma.image-id /> <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.login-user>
<test.cloudsigma.image.authenticate-sudo /> <test.cloudsigma.image.authenticate-sudo></test.cloudsigma.image.authenticate-sudo>
</properties> </properties>
<dependencies> <dependencies>
@ -94,7 +95,8 @@
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<test.cloudsigma.endpoint>${test.cloudsigma.endpoint}</test.cloudsigma.endpoint> <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.identity>${test.cloudsigma.identity}</test.cloudsigma.identity>
<test.cloudsigma.credential>${test.cloudsigma.credential}</test.cloudsigma.credential> <test.cloudsigma.credential>${test.cloudsigma.credential}</test.cloudsigma.credential>
<test.cloudsigma.image-id>${test.cloudsigma.image-id}</test.cloudsigma.image-id> <test.cloudsigma.image-id>${test.cloudsigma.image-id}</test.cloudsigma.image-id>

View File

@ -18,7 +18,6 @@
*/ */
package org.jclouds.cloudsigma; package org.jclouds.cloudsigma;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
@ -28,7 +27,6 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jclouds.Constants;
import org.jclouds.cloudsigma.domain.ClaimType; import org.jclouds.cloudsigma.domain.ClaimType;
import org.jclouds.cloudsigma.domain.CreateDriveRequest; import org.jclouds.cloudsigma.domain.CreateDriveRequest;
import org.jclouds.cloudsigma.domain.DriveData; import org.jclouds.cloudsigma.domain.DriveData;
@ -46,6 +44,8 @@ import org.jclouds.cloudsigma.domain.VLANInfo;
import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.cloudsigma.predicates.DriveClaimed; import org.jclouds.cloudsigma.predicates.DriveClaimed;
import org.jclouds.cloudsigma.util.Servers; 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.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
@ -62,6 +62,7 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -73,56 +74,39 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", singleThreaded = true) @Test(groups = "live", singleThreaded = true, testName = "CloudSigmaClientLiveTest")
public class CloudSigmaClientLiveTest { public class CloudSigmaClientLiveTest extends BaseVersionedServiceLiveTest {
public CloudSigmaClientLiveTest() {
provider = "cloudsigma";
}
protected long driveSize = 8 * 1024 * 1024 * 1024l; protected long driveSize = 8 * 1024 * 1024 * 1024l;
protected int maxDriveImageTime = 300; protected int maxDriveImageTime = 300;
protected String vncPassword = "Il0veVNC"; protected String vncPassword = "Il0veVNC";
protected String bootDrive = "f3c7c665-cd54-4a78-8fd2-7ec2f028cf29";
protected CloudSigmaClient client; protected CloudSigmaClient client;
protected RestContext<CloudSigmaClient, CloudSigmaAsyncClient> context; protected RestContext<CloudSigmaClient, CloudSigmaAsyncClient> context;
protected Predicate<IPSocket> socketTester; 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 Predicate<DriveInfo> driveNotClaimed;
protected ComputeServiceContext computeContext;
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") @BeforeGroups(groups = "live")
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider, computeContext = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides);
context = computeContext.getProviderSpecificContext();
client = context.getApi(); client = context.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS); 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1, socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS); TimeUnit.SECONDS);
if (Strings.emptyToNull(imageId) == null) {
imageId = computeContext.getComputeService().templateBuilder().build().getImage().getId();
}
} }
@Test @Test
@ -459,7 +443,7 @@ public class CloudSigmaClientLiveTest {
protected void prepareDrive() { protected void prepareDrive() {
client.destroyDrive(drive.getUuid()); client.destroyDrive(drive.getUuid());
drive = client.cloneDrive(bootDrive, drive.getName(), drive = client.cloneDrive(imageId, drive.getName(),
new CloneDriveOptions() new CloneDriveOptions()
.size(driveSize) .size(driveSize)
.tags("cat:mouse", "monkey:banana") .tags("cat:mouse", "monkey:banana")

View File

@ -49,7 +49,8 @@
<properties> <properties>
<test.cloudstack.endpoint>http://localhost:8080/client/api</test.cloudstack.endpoint> <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.identity>FIXME_apiKey</test.cloudstack.identity>
<test.cloudstack.credential>FIXME_secretKey</test.cloudstack.credential> <test.cloudstack.credential>FIXME_secretKey</test.cloudstack.credential>
<test.cloudstack.domainAdminIdentity /> <test.cloudstack.domainAdminIdentity />
@ -116,7 +117,8 @@
<threadCount>2</threadCount> <threadCount>2</threadCount>
<systemPropertyVariables> <systemPropertyVariables>
<test.cloudstack.endpoint>${test.cloudstack.endpoint}</test.cloudstack.endpoint> <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.identity>${test.cloudstack.identity}</test.cloudstack.identity>
<test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential> <test.cloudstack.credential>${test.cloudstack.credential}</test.cloudstack.credential>
<test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id> <test.cloudstack.image-id>${test.cloudstack.image-id}</test.cloudstack.image-id>

View File

@ -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; package org.jclouds.cloudstack;
import org.jclouds.cloudstack.internal.CloudStackContextImpl; import org.jclouds.cloudstack.internal.CloudStackContextImpl;
@ -15,6 +33,10 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(CloudStackContextImpl.class) @ImplementedBy(CloudStackContextImpl.class)
public interface CloudStackContext extends ComputeServiceContext { public interface CloudStackContext extends ComputeServiceContext {
@SuppressWarnings("unchecked")
@Override
RestContext<CloudStackClient, CloudStackAsyncClient> getProviderSpecificContext();
RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext(); RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext();
RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> getGlobalContext(); RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> getGlobalContext();

View File

@ -21,6 +21,8 @@ package org.jclouds.cloudstack;
import org.jclouds.cloudstack.features.GlobalAccountAsyncClient; import org.jclouds.cloudstack.features.GlobalAccountAsyncClient;
import org.jclouds.cloudstack.features.GlobalAlertAsyncClient; import org.jclouds.cloudstack.features.GlobalAlertAsyncClient;
import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient; 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.GlobalHostAsyncClient;
import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient; import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient; import org.jclouds.cloudstack.features.GlobalStoragePoolAsyncClient;
@ -90,4 +92,11 @@ public interface CloudStackGlobalAsyncClient extends CloudStackDomainAsyncClient
*/ */
@Delegate @Delegate
GlobalUsageAsyncClient getUsageClient(); GlobalUsageAsyncClient getUsageClient();
/**
* Provides asynchronous access to Configuration
*/
@Delegate
@Override
GlobalConfigurationAsyncClient getConfigurationClient();
} }

View File

@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.features.GlobalAccountClient; import org.jclouds.cloudstack.features.GlobalAccountClient;
import org.jclouds.cloudstack.features.GlobalAlertClient; import org.jclouds.cloudstack.features.GlobalAlertClient;
import org.jclouds.cloudstack.features.GlobalCapacityClient; import org.jclouds.cloudstack.features.GlobalCapacityClient;
import org.jclouds.cloudstack.features.GlobalConfigurationClient;
import org.jclouds.cloudstack.features.GlobalHostClient; import org.jclouds.cloudstack.features.GlobalHostClient;
import org.jclouds.cloudstack.features.GlobalOfferingClient; import org.jclouds.cloudstack.features.GlobalOfferingClient;
import org.jclouds.cloudstack.features.GlobalStoragePoolClient; import org.jclouds.cloudstack.features.GlobalStoragePoolClient;
@ -94,4 +95,11 @@ public interface CloudStackGlobalClient extends CloudStackDomainClient {
*/ */
@Delegate @Delegate
GlobalUsageClient getUsageClient(); GlobalUsageClient getUsageClient();
/**
* Provides synchronous access to Configuration
*/
@Delegate
@Override
GlobalConfigurationClient getConfigurationClient();
} }

View File

@ -19,6 +19,7 @@
package org.jclouds.cloudstack; package org.jclouds.cloudstack;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import java.util.Properties; import java.util.Properties;
@ -33,6 +34,7 @@ public class CloudStackPropertiesBuilder extends PropertiesBuilder {
@Override @Override
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8080/client/api");
properties.setProperty(PROPERTY_API_VERSION, "2.2"); properties.setProperty(PROPERTY_API_VERSION, "2.2");
properties.setProperty("jclouds.ssh.max-retries", "7"); properties.setProperty("jclouds.ssh.max-retries", "7");
properties.setProperty("jclouds.ssh.retry-auth", "true"); properties.setProperty("jclouds.ssh.retry-auth", "true");

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.jclouds.cloudstack.CloudStackAsyncClient; import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
@ -38,9 +39,13 @@ import org.jclouds.cloudstack.compute.functions.TemplateToOperatingSystem;
import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata; import org.jclouds.cloudstack.compute.functions.VirtualMachineToNodeMetadata;
import org.jclouds.cloudstack.compute.functions.ZoneToLocation; import org.jclouds.cloudstack.compute.functions.ZoneToLocation;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; 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.CloudStackComputeServiceAdapter;
import org.jclouds.cloudstack.compute.strategy.OptionsConverter;
import org.jclouds.cloudstack.domain.IPForwardingRule; import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.OSType; import org.jclouds.cloudstack.domain.OSType;
import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template; import org.jclouds.cloudstack.domain.Template;
@ -49,9 +54,11 @@ import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.features.GuestOSClient; import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork; import org.jclouds.cloudstack.functions.StaticNATVirtualMachineInNetwork;
import org.jclouds.cloudstack.functions.ZoneIdToZone;
import org.jclouds.cloudstack.predicates.JobComplete; import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.cloudstack.suppliers.GetCurrentUser; import org.jclouds.cloudstack.suppliers.GetCurrentUser;
import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser; import org.jclouds.cloudstack.suppliers.NetworksForCurrentUser;
import org.jclouds.cloudstack.suppliers.ZoneIdToZoneSupplier;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule; import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
@ -108,6 +115,10 @@ public class CloudStackComputeServiceContextModule
install(new FactoryModuleBuilder().build(StaticNATVirtualMachineInNetwork.Factory.class)); install(new FactoryModuleBuilder().build(StaticNATVirtualMachineInNetwork.Factory.class));
bind(new TypeLiteral<CacheLoader<Long, Set<IPForwardingRule>>>() { bind(new TypeLiteral<CacheLoader<Long, Set<IPForwardingRule>>>() {
}).to(GetIPForwardingRulesByVirtualMachine.class); }).to(GetIPForwardingRulesByVirtualMachine.class);
bind(new TypeLiteral<CacheLoader<Long, Zone>>() {
}).to(ZoneIdToZone.class);
bind(new TypeLiteral<Supplier<LoadingCache<Long, Zone>>>() {
}).to(ZoneIdToZoneSupplier.class);
} }
@Provides @Provides
@ -198,4 +209,11 @@ public class CloudStackComputeServiceContextModule
} }
} }
@Provides
@Singleton
Map<NetworkType, ? extends OptionsConverter> optionsConverters(){
return ImmutableMap.of(
NetworkType.ADVANCED, new AdvancedNetworkOptionsConverter(),
NetworkType.BASIC, new BasicNetworkOptionsConverter());
}
} }

View File

@ -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; package org.jclouds.cloudstack.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -20,27 +20,33 @@ package org.jclouds.cloudstack.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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.base.Predicates.and;
import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.cloudstack.options.DeployVirtualMachineOptions.Builder.displayName; 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.NetworkPredicates.supportsStaticNAT;
import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady; import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; 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.CloudStackClient;
import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.IPForwardingRule; import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkType;
import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template; import org.jclouds.cloudstack.domain.Template;
@ -88,6 +94,8 @@ public class CloudStackComputeServiceAdapter implements
private final CreatePortForwardingRulesForIP setupPortForwardingRulesForIP; private final CreatePortForwardingRulesForIP setupPortForwardingRulesForIP;
private final LoadingCache<Long, Set<IPForwardingRule>> vmToRules; private final LoadingCache<Long, Set<IPForwardingRule>> vmToRules;
private final Map<String, Credentials> credentialStore; private final Map<String, Credentials> credentialStore;
private final Map<NetworkType, ? extends OptionsConverter> optionsConverters;
private final Supplier<LoadingCache<Long, Zone>> zoneIdToZone;
@Inject @Inject
public CloudStackComputeServiceAdapter(CloudStackClient client, Predicate<Long> jobComplete, public CloudStackComputeServiceAdapter(CloudStackClient client, Predicate<Long> jobComplete,
@ -95,7 +103,8 @@ public class CloudStackComputeServiceAdapter implements
BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult, BlockUntilJobCompletesAndReturnResult blockUntilJobCompletesAndReturnResult,
StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork, StaticNATVirtualMachineInNetwork.Factory staticNATVMInNetwork,
CreatePortForwardingRulesForIP setupPortForwardingRulesForIP, LoadingCache<Long, Set<IPForwardingRule>> vmToRules, 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.client = checkNotNull(client, "client");
this.jobComplete = checkNotNull(jobComplete, "jobComplete"); this.jobComplete = checkNotNull(jobComplete, "jobComplete");
this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier"); this.networkSupplier = checkNotNull(networkSupplier, "networkSupplier");
@ -105,6 +114,8 @@ public class CloudStackComputeServiceAdapter implements
this.setupPortForwardingRulesForIP = checkNotNull(setupPortForwardingRulesForIP, "setupPortForwardingRulesForIP"); this.setupPortForwardingRulesForIP = checkNotNull(setupPortForwardingRulesForIP, "setupPortForwardingRulesForIP");
this.vmToRules = checkNotNull(vmToRules, "vmToRules"); this.vmToRules = checkNotNull(vmToRules, "vmToRules");
this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.optionsConverters = optionsConverters;
this.zoneIdToZone = zoneIdToZone;
} }
@Override @Override
@ -118,30 +129,19 @@ public class CloudStackComputeServiceAdapter implements
Map<Long, Network> networks = networkSupplier.get(); Map<Long, Network> networks = networkSupplier.get();
final long zoneId = Long.parseLong(template.getLocation().getId()); 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); CloudStackTemplateOptions templateOptions = template.getOptions().as(CloudStackTemplateOptions.class);
DeployVirtualMachineOptions options = displayName(name).name(name); checkState(optionsConverters.containsKey(zone.getNetworkType()), "no options converter configured for network type %s",zone.getNetworkType());
if (templateOptions.getSecurityGroupIds().size() > 0) { DeployVirtualMachineOptions options = DeployVirtualMachineOptions.Builder.displayName(name).name(name);
options.securityGroupIds(templateOptions.getSecurityGroupIds()); OptionsConverter optionsConverter = optionsConverters.get(zone.getNetworkType());
} else if (templateOptions.getNetworkIds().size() > 0) { options = optionsConverter.apply(templateOptions, networks, zoneId, options);
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);
}
if (templateOptions.getIpOnDefaultNetwork() != null) { if (templateOptions.getIpOnDefaultNetwork() != null) {
options.ipOnDefaultNetwork(templateOptions.getIpOnDefaultNetwork()); options.ipOnDefaultNetwork(templateOptions.getIpOnDefaultNetwork());

View File

@ -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);
}

View File

@ -28,6 +28,7 @@ import javax.inject.Singleton;
import org.jclouds.cloudstack.domain.Account; import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.Account.State; import org.jclouds.cloudstack.domain.Account.State;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.User; import org.jclouds.cloudstack.domain.User;
@ -47,11 +48,12 @@ import com.google.inject.TypeLiteral;
/** /**
* Configures the cloudstack parsers. * Configures the cloudstack parsers.
* *
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
public class CloudStackParserModule extends AbstractModule { 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) { public JsonElement serialize(PortForwardingRule src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src); return context.serialize(src);
@ -85,10 +87,10 @@ public class CloudStackParserModule extends AbstractModule {
private long IPAddressId; private long IPAddressId;
@SerializedName("privateport") @SerializedName("privateport")
private int privatePort; private int privatePort;
private String protocol; private PortForwardingRule.Protocol protocol;
@SerializedName("publicport") @SerializedName("publicport")
public int publicPort; public int publicPort;
private String state; private PortForwardingRule.State state;
@SerializedName("virtualmachinedisplayname") @SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
@SerializedName("virtualmachineid") @SerializedName("virtualmachineid")
@ -104,6 +106,52 @@ public class CloudStackParserModule extends AbstractModule {
} }
} }
@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 @Singleton
public static class LoadBalancerRuleAdapter implements JsonSerializer<LoadBalancerRule>, JsonDeserializer<LoadBalancerRule> { public static class LoadBalancerRuleAdapter implements JsonSerializer<LoadBalancerRule>, JsonDeserializer<LoadBalancerRule> {
@ -240,7 +288,8 @@ public class CloudStackParserModule extends AbstractModule {
}).toInstance(ImmutableMap.<Type, Object>of( }).toInstance(ImmutableMap.<Type, Object>of(
Account.class, new BreakGenericSetAdapter(), Account.class, new BreakGenericSetAdapter(),
LoadBalancerRule.class, new LoadBalancerRuleAdapter(), LoadBalancerRule.class, new LoadBalancerRuleAdapter(),
PortForwardingRule.class, new PortForwardingRuleAdaptor() PortForwardingRule.class, new PortForwardingRuleAdapter(),
FirewallRule.class, new FirewallRuleAdapter()
)); ));
} }

View File

@ -54,6 +54,8 @@ import org.jclouds.cloudstack.features.GlobalAlertAsyncClient;
import org.jclouds.cloudstack.features.GlobalAlertClient; import org.jclouds.cloudstack.features.GlobalAlertClient;
import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient; import org.jclouds.cloudstack.features.GlobalCapacityAsyncClient;
import org.jclouds.cloudstack.features.GlobalCapacityClient; 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.GlobalHostAsyncClient;
import org.jclouds.cloudstack.features.GlobalHostClient; import org.jclouds.cloudstack.features.GlobalHostClient;
import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient; import org.jclouds.cloudstack.features.GlobalOfferingAsyncClient;
@ -138,6 +140,7 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
.put(GuestOSClient.class, GuestOSAsyncClient.class)// .put(GuestOSClient.class, GuestOSAsyncClient.class)//
.put(HypervisorClient.class, HypervisorAsyncClient.class)// .put(HypervisorClient.class, HypervisorAsyncClient.class)//
.put(ConfigurationClient.class, ConfigurationAsyncClient.class)// .put(ConfigurationClient.class, ConfigurationAsyncClient.class)//
.put(GlobalConfigurationClient.class, GlobalConfigurationAsyncClient.class)//
.put(AccountClient.class, AccountAsyncClient.class)// .put(AccountClient.class, AccountAsyncClient.class)//
.put(DomainAccountClient.class, DomainAccountAsyncClient.class)// .put(DomainAccountClient.class, DomainAccountAsyncClient.class)//
.put(DomainUserClient.class, DomainUserAsyncClient.class)// .put(DomainUserClient.class, DomainUserAsyncClient.class)//

View File

@ -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);
}
}

View File

@ -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 + '\'' +
'}';
}
}

View File

@ -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 + '\'' +
'}';
}
}

View File

@ -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; package org.jclouds.cloudstack.domain;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;

View File

@ -20,15 +20,58 @@ package org.jclouds.cloudstack.domain;
import java.util.Set; import java.util.Set;
import com.google.common.base.Joiner; import com.google.common.base.CaseFormat;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
/** /**
* @author Adrian Cole * @author Adrian Cole, Andrei Savu
*/ */
public class PortForwardingRule implements Comparable<PortForwardingRule> { 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() { public static Builder builder() {
return new Builder(); return new Builder();
} }
@ -38,9 +81,9 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
private String IPAddress; private String IPAddress;
private long IPAddressId; private long IPAddressId;
private int privatePort; private int privatePort;
private String protocol; private Protocol protocol;
public int publicPort; public int publicPort;
private String state; private State state;
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
public long virtualMachineId; public long virtualMachineId;
private String virtualMachineName; private String virtualMachineName;
@ -68,7 +111,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
return this; return this;
} }
public Builder protocol(String protocol) { public Builder protocol(Protocol protocol) {
this.protocol = protocol; this.protocol = protocol;
return this; return this;
} }
@ -78,7 +121,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
return this; return this;
} }
public Builder state(String state) { public Builder state(State state) {
this.state = state; this.state = state;
return this; return this;
} }
@ -126,10 +169,10 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
private long IPAddressId; private long IPAddressId;
@SerializedName("privateport") @SerializedName("privateport")
private int privatePort; private int privatePort;
private String protocol; private Protocol protocol;
@SerializedName("publicport") @SerializedName("publicport")
public int publicPort; public int publicPort;
private String state; private State state;
@SerializedName("virtualmachinedisplayname") @SerializedName("virtualmachinedisplayname")
private String virtualMachineDisplayName; private String virtualMachineDisplayName;
@SerializedName("virtualmachineid") @SerializedName("virtualmachineid")
@ -143,8 +186,8 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
@SerializedName("publicendport") @SerializedName("publicendport")
private int publicEndPort; private int publicEndPort;
public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, String protocol, public PortForwardingRule(long id, String iPAddress, long iPAddressId, int privatePort, Protocol protocol,
int publicPort, String state, String virtualMachineDisplayName, long virtualMachineId, int publicPort, State state, String virtualMachineDisplayName, long virtualMachineId,
String virtualMachineName, Set<String> CIDRs, int privateEndPort, int publicEndPort) { String virtualMachineName, Set<String> CIDRs, int privateEndPort, int publicEndPort) {
this.id = id; this.id = id;
this.IPAddress = iPAddress; this.IPAddress = iPAddress;
@ -197,7 +240,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
/** /**
* @return the protocol of the port forwarding rule * @return the protocol of the port forwarding rule
*/ */
public String getProtocol() { public Protocol getProtocol() {
return protocol; return protocol;
} }
@ -211,7 +254,7 @@ public class PortForwardingRule implements Comparable<PortForwardingRule> {
/** /**
* @return the state of the rule * @return the state of the rule
*/ */
public String getState() { public State getState() {
return state; return state;
} }

View File

@ -26,15 +26,20 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.filters.QuerySigner; 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.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement;
import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.Unwrap; import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -43,14 +48,53 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides asynchronous access to cloudstack via their REST API. * Provides asynchronous access to cloudstack via their REST API.
* <p/> * <p/>
* *
* @author Adrian Cole
* @see FirewallClient * @see FirewallClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" /> * @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
* @author Adrian Cole
*/ */
@RequestFilters(QuerySigner.class) @RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json") @QueryParams(keys = "response", values = "json")
public interface FirewallAsyncClient { 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 * @see FirewallClient#listPortForwardingRules
*/ */
@ -61,6 +105,17 @@ public interface FirewallAsyncClient {
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<PortForwardingRule>> listPortForwardingRules(ListPortForwardingRulesOptions... options); 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 * @see FirewallClient#createPortForwardingRuleForVirtualMachine
*/ */
@ -69,9 +124,9 @@ public interface FirewallAsyncClient {
@Unwrap @Unwrap
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<AsyncCreateResponse> createPortForwardingRuleForVirtualMachine( ListenableFuture<AsyncCreateResponse> createPortForwardingRuleForVirtualMachine(
@QueryParam("virtualmachineid") long virtualMachineId, @QueryParam("ipaddressid") long IPAddressId, @QueryParam("ipaddressid") long ipAddressId, @QueryParam("protocol") PortForwardingRule.Protocol protocol,
@QueryParam("protocol") String protocol, @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort, @QueryParam("virtualmachineid") long virtualMachineId,
@QueryParam("publicport") int publicPort); @QueryParam("privateport") int privatePort);
/** /**
* @see FirewallClient#deletePortForwardingRule * @see FirewallClient#deletePortForwardingRule

View File

@ -22,7 +22,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.PortForwardingRule; 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.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
@ -36,6 +39,49 @@ import org.jclouds.concurrent.Timeout;
*/ */
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface FirewallClient { 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 * List the port forwarding rules
* *
@ -46,24 +92,33 @@ public interface FirewallClient {
*/ */
Set<PortForwardingRule> listPortForwardingRules(ListPortForwardingRulesOptions... options); 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 * Creates an port forwarding rule
* *
* @param virtualMachineId *
* the ID of the virtual machine for the port forwarding rule * @param ipAddressId
* @param IPAddressId
* the public IP address id of the forwarding rule, already
* associated via associatePort
* @param protocol * @param protocol
* the protocol for the rule. Valid values are TCP or UDP. * the protocol for the rule. Valid values are TCP or UDP.
* @param privatePort
* the private port of the port forwarding rule
* @param publicPort * @param publicPort
* the public port of the port forwarding rule * 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 * @return response used to track creation
*/ */
AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long virtualMachineId, long IPAddressId, AsyncCreateResponse createPortForwardingRuleForVirtualMachine(long ipAddressId,
String protocol, int privatePort, int publicPort); PortForwardingRule.Protocol protocol, int publicPort, long virtualMachineId, int privatePort);
/** /**
* Deletes an port forwarding rule * Deletes an port forwarding rule
@ -71,5 +126,5 @@ public interface FirewallClient {
* @param id * @param id
* the id of the forwarding rule * the id of the forwarding rule
*/ */
void deletePortForwardingRule(long id); Void deletePortForwardingRule(long id);
} }

View File

@ -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);
}

View File

@ -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);
}

View File

@ -19,8 +19,10 @@
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host; import org.jclouds.cloudstack.domain.Host;
import org.jclouds.cloudstack.filters.QuerySigner; import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.ListClustersOptions;
import org.jclouds.cloudstack.options.ListHostsOptions; import org.jclouds.cloudstack.options.ListHostsOptions;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.QueryParams;
@ -54,4 +56,14 @@ public interface GlobalHostAsyncClient {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Host>> listHosts(ListHostsOptions... options); 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);
} }

View File

@ -18,7 +18,9 @@
*/ */
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host; import org.jclouds.cloudstack.domain.Host;
import org.jclouds.cloudstack.options.ListClustersOptions;
import org.jclouds.cloudstack.options.ListHostsOptions; import org.jclouds.cloudstack.options.ListHostsOptions;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
@ -46,4 +48,11 @@ public interface GlobalHostClient {
*/ */
Set<Host> listHosts(ListHostsOptions... options); 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);
} }

View File

@ -29,7 +29,9 @@ import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.filters.QuerySigner; import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions; import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.functions.JoinOnComma; import org.jclouds.functions.JoinOnComma;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.OnlyElement; import org.jclouds.rest.annotations.OnlyElement;
@ -76,7 +78,7 @@ public interface LoadBalancerAsyncClient {
ListenableFuture<LoadBalancerRule> getLoadBalancerRule(@QueryParam("id") long id); ListenableFuture<LoadBalancerRule> getLoadBalancerRule(@QueryParam("id") long id);
/** /**
* @see LoadBalancerClient#createLoadBalancerRuleForPublicIp * @see LoadBalancerClient#createLoadBalancerRuleForPublicIP
*/ */
@GET @GET
@QueryParams(keys = "command", values = "createLoadBalancerRule") @QueryParams(keys = "command", values = "createLoadBalancerRule")
@ -84,7 +86,19 @@ public interface LoadBalancerAsyncClient {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Long> createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId, ListenableFuture<Long> createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId,
@QueryParam("algorithm") Algorithm algorithm, @QueryParam("name") String name, @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 * @see LoadBalancerClient#deleteLoadBalancerRule

View File

@ -24,7 +24,9 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions; import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
/** /**
@ -72,10 +74,22 @@ public interface LoadBalancerClient {
* @param publicPort * @param publicPort
* public ip address id from where the network traffic will be load * public ip address id from where the network traffic will be load
* balanced from * balanced from
* @param options optional call arguments
* @return newly created rule * @return newly created rule
*/ */
Long createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name, 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);
/** /**
* *

View File

@ -16,30 +16,35 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.json.internal; 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; 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 * Defines a cache that allows a zone to be looked up by its ID.
* 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 * @author Richard Downer
* @see <a href="http://code.google.com/p/google-gson/issues/detail?id=326"/>
*/ */
public final class JsonLiteral extends JsonElement { public class ZoneIdToZone extends CacheLoader<Long, Zone> {
private final CharSequence literal;
public JsonLiteral(CharSequence literal) { private final ZoneClient zoneClient;
this.literal = checkNotNull(literal, "literal");
@Inject
public ZoneIdToZone(CloudStackClient client) {
checkNotNull(client, "client");
this.zoneClient = client.getZoneClient();
} }
@Override @Override
public String toString() { public Zone load(Long zoneId) throws Exception {
return literal.toString(); checkNotNull(zoneId, "zoneId");
return zoneClient.getZone(zoneId);
} }
} }

View File

@ -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; package org.jclouds.cloudstack.internal;
import java.util.Map; import java.util.Map;
@ -24,19 +42,27 @@ import org.jclouds.rest.RestContext;
@Singleton @Singleton
public class CloudStackContextImpl extends ComputeServiceContextImpl<CloudStackClient, CloudStackAsyncClient> implements public class CloudStackContextImpl extends ComputeServiceContextImpl<CloudStackClient, CloudStackAsyncClient> implements
CloudStackContext { CloudStackContext {
private final RestContext<CloudStackClient,CloudStackAsyncClient> providerSpecificContext;
private final RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext; private final RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext;
private final RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext; private final RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext;
@Inject @Inject
public CloudStackContextImpl(ComputeService computeService, Map<String, Credentials> credentialStore, Utils utils, public CloudStackContextImpl(ComputeService computeService, Map<String, Credentials> credentialStore, Utils utils,
@SuppressWarnings("rawtypes") RestContext providerSpecificContext, RestContext<CloudStackClient,CloudStackAsyncClient> providerSpecificContext,
RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext, RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> domainContext,
RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext) { RestContext<CloudStackGlobalClient, CloudStackGlobalAsyncClient> globalContext) {
super(computeService, credentialStore, utils, providerSpecificContext); super(computeService, credentialStore, utils, providerSpecificContext);
this.providerSpecificContext=providerSpecificContext;
this.domainContext = domainContext; this.domainContext = domainContext;
this.globalContext = globalContext; this.globalContext = globalContext;
} }
@SuppressWarnings("unchecked")
@Override
public RestContext<CloudStackClient,CloudStackAsyncClient> getProviderSpecificContext() {
return providerSpecificContext;
}
@Override @Override
public RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext() { public RestContext<CloudStackDomainClient, CloudStackDomainAsyncClient> getDomainContext() {
return domainContext; return domainContext;

View File

@ -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);
}
}
}

View File

@ -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));
}
}

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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));
}
}

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -66,7 +66,30 @@ public class ListLoadBalancerRulesOptions extends AccountInDomainOptions {
public ListLoadBalancerRulesOptions virtualMachineId(long virtualMachineId) { public ListLoadBalancerRulesOptions virtualMachineId(long virtualMachineId) {
this.queryParameters.replaceValues("virtualmachineid", ImmutableSet.of(virtualMachineId + "")); this.queryParameters.replaceValues("virtualmachineid", ImmutableSet.of(virtualMachineId + ""));
return this; 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 { public static class Builder {
@ -118,6 +141,30 @@ public class ListLoadBalancerRulesOptions extends AccountInDomainOptions {
ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions(); ListLoadBalancerRulesOptions options = new ListLoadBalancerRulesOptions();
return options.virtualMachineId(virtualMachineId); 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);
}
} }
/** /**

View File

@ -23,26 +23,52 @@ import com.google.common.collect.ImmutableSet;
/** /**
* Options used to control what port forwarding rules are returned * 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 * @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 class ListPortForwardingRulesOptions extends AccountInDomainOptions {
public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions(); public static final ListPortForwardingRulesOptions NONE = new ListPortForwardingRulesOptions();
/**
* @param id
* lists rule with the specified ID
*/
public ListPortForwardingRulesOptions id(long id) {
this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
return this;
}
/** /**
* @param IPAddressId * @param IPAddressId
* list the rule belonging to this public ip address * list the rule belonging to this public ip address
*/ */
public ListPortForwardingRulesOptions IPAddressId(long IPAddressId) { public ListPortForwardingRulesOptions ipAddressId(long IPAddressId) {
this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(IPAddressId + "")); this.queryParameters.replaceValues("ipaddressid", ImmutableSet.of(IPAddressId + ""));
return this; return this;
} }
public static class Builder { 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 * @see ListPortForwardingRulesOptions#accountInDomain
*/ */
@ -51,14 +77,6 @@ public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
return options.accountInDomain(account, domain); return options.accountInDomain(account, domain);
} }
/**
* @see ListPortForwardingRulesOptions#IPAddressId
*/
public static ListPortForwardingRulesOptions IPAddressId(long IPAddressId) {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.IPAddressId(IPAddressId);
}
/** /**
* @see ListPortForwardingRulesOptions#domainId * @see ListPortForwardingRulesOptions#domainId
*/ */
@ -66,7 +84,6 @@ public class ListPortForwardingRulesOptions extends AccountInDomainOptions {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions(); ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions();
return options.domainId(id); return options.domainId(id);
} }
} }
/** /**

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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.
*/
/** /**
* Licensed to jclouds, Inc. (jclouds) under one or more * Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file * contributor license agreements. See the NOTICE file

View File

@ -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);
}
}
}

View File

@ -93,6 +93,19 @@ public class NetworkPredicates {
} }
} }
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> { public static class NetworkServiceNamed implements Predicate<NetworkService> {
private final String name; private final String name;
@ -189,6 +202,16 @@ public class NetworkPredicates {
return IsVirtualNetwork.INSTANCE; return IsVirtualNetwork.INSTANCE;
} }
/**
* 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. * @return always returns true.

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -21,6 +21,7 @@ package org.jclouds.cloudstack.features;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions; import org.jclouds.cloudstack.options.ListPortForwardingRulesOptions;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed; import org.jclouds.http.functions.ParseFirstJsonValueNamed;
@ -64,7 +65,7 @@ public class FirewallAsyncClientTest extends BaseCloudStackAsyncClientTest<Firew
public void testListPortForwardingRulesOptions() throws SecurityException, NoSuchMethodException, IOException { public void testListPortForwardingRulesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = FirewallAsyncClient.class.getMethod("listPortForwardingRules", Method method = FirewallAsyncClient.class.getMethod("listPortForwardingRules",
ListPortForwardingRulesOptions[].class); ListPortForwardingRulesOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.IPAddressId(3)); HttpRequest httpRequest = processor.createRequest(method, ListPortForwardingRulesOptions.Builder.ipAddressId(3));
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listPortForwardingRules&ipaddressid=3 HTTP/1.1"); "GET http://localhost:8080/client/api?response=json&command=listPortForwardingRules&ipaddressid=3 HTTP/1.1");
@ -82,12 +83,12 @@ public class FirewallAsyncClientTest extends BaseCloudStackAsyncClientTest<Firew
public void testCreatePortForwardingRuleForVirtualMachine() throws SecurityException, NoSuchMethodException, public void testCreatePortForwardingRuleForVirtualMachine() throws SecurityException, NoSuchMethodException,
IOException { IOException {
Method method = FirewallAsyncClient.class.getMethod("createPortForwardingRuleForVirtualMachine", long.class, Method method = FirewallAsyncClient.class.getMethod("createPortForwardingRuleForVirtualMachine", long.class,
long.class, String.class, int.class, int.class); PortForwardingRule.Protocol.class, int.class, long.class, int.class);
HttpRequest httpRequest = processor.createRequest(method, 6, 7, "tcp", 22, 22); HttpRequest httpRequest = processor.createRequest(method, 6L, PortForwardingRule.Protocol.TCP, 22, 7L, 22);
assertRequestLineEquals( assertRequestLineEquals(
httpRequest, 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"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);

View File

@ -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();
}
}

View File

@ -19,18 +19,22 @@
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import static com.google.common.collect.Iterables.find; 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.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import com.google.common.base.Predicates;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.FirewallRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.domain.VirtualMachine; 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.jclouds.net.IPSocket;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
@ -38,6 +42,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import javax.annotation.Nullable;
/** /**
* Tests behavior of {@code FirewallClientLiveTest} * Tests behavior of {@code FirewallClientLiveTest}
* *
@ -47,7 +53,10 @@ import com.google.common.base.Predicate;
public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest { public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null; private PublicIPAddress ip = null;
private VirtualMachine vm; private VirtualMachine vm;
private PortForwardingRule rule;
private FirewallRule firewallRule;
private PortForwardingRule portForwardingRule;
private Network network; private Network network;
private boolean networksDisabled; private boolean networksDisabled;
@ -56,13 +65,25 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
super.setupClient(); super.setupClient();
prefix += "rule"; prefix += "rule";
try { 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; Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network,
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete, defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
virtualMachineRunning); client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption()) if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
networksDisabled = true; networksDisabled = true;
} }
@ -71,30 +92,75 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
public void testCreatePortForwardingRule() throws Exception { public void testCreatePortForwardingRule() throws Exception {
if (networksDisabled) if (networksDisabled)
return; return;
while (rule == null) { while (portForwardingRule == null) {
ip = reuseOrAssociate.apply(network); ip = reuseOrAssociate.apply(network);
try { try {
AsyncCreateResponse job = client.getFirewallClient().createPortForwardingRuleForVirtualMachine(vm.getId(), AsyncCreateResponse job = client.getFirewallClient()
ip.getId(), "tcp", 22, 22); .createPortForwardingRuleForVirtualMachine(ip.getId(), PortForwardingRule.Protocol.TCP, 22, vm.getId(), 22);
assertTrue(jobComplete.apply(job.getJobId())); assertTrue(jobComplete.apply(job.getJobId()));
rule = findRuleWithId(job.getId()); portForwardingRule = client.getFirewallClient().getPortForwardingRule(job.getId());
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
Logger.CONSOLE.error("Failed while trying to allocate ip: " + e);
// very likely an ip conflict, so retry; // very likely an ip conflict, so retry;
} }
} }
assertEquals(rule.getIPAddressId(), ip.getId()); assertEquals(portForwardingRule.getIPAddressId(), ip.getId());
assertEquals(rule.getVirtualMachineId(), vm.getId()); assertEquals(portForwardingRule.getVirtualMachineId(), vm.getId());
assertEquals(rule.getPublicPort(), 22); assertEquals(portForwardingRule.getPublicPort(), 22);
assertEquals(rule.getProtocol(), "tcp"); assertEquals(portForwardingRule.getProtocol(), "tcp");
checkRule(rule);
checkPortForwardingRule(portForwardingRule);
checkSSH(new IPSocket(ip.getIPAddress(), 22)); 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") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {
if (rule != null) { if (firewallRule != null) {
client.getFirewallClient().deletePortForwardingRule(rule.getId()); client.getFirewallClient().deleteFirewallRule(firewallRule.getId());
}
if (portForwardingRule != null) {
client.getFirewallClient().deletePortForwardingRule(portForwardingRule.getId());
} }
if (vm != null) { if (vm != null) {
jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId())); jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId()));
@ -105,30 +171,18 @@ public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
super.tearDown(); super.tearDown();
} }
public void testListPortForwardingRules() throws Exception { protected void checkFirewallRule(FirewallRule rule) {
Set<PortForwardingRule> response = client.getFirewallClient().listPortForwardingRules(); assertEquals(rule,
assert null != response; client.getFirewallClient().getFirewallRule(rule.getId()));
assertTrue(response.size() >= 0); assert rule.getId() > 0 : rule;
for (final PortForwardingRule rule : response) { assert rule.getStartPort() > 0 : rule;
PortForwardingRule newDetails = findRuleWithId(rule.getId()); assert rule.getEndPort() >= rule.getStartPort() : rule;
assertEquals(rule.getId(), newDetails.getId()); assert rule.getProtocol() != null;
checkRule(rule);
}
} }
private PortForwardingRule findRuleWithId(final long id) { protected void checkPortForwardingRule(PortForwardingRule rule) {
return find(client.getFirewallClient().listPortForwardingRules(), new Predicate<PortForwardingRule>() { assertEquals(rule,
client.getFirewallClient().getPortForwardingRule(rule.getId()));
@Override
public boolean apply(PortForwardingRule arg0) {
return arg0.getId() == id;
}
});
}
protected void checkRule(PortForwardingRule rule) {
assertEquals(rule.getId(), findRuleWithId(rule.getId()).getId());
assert rule.getId() > 0 : rule; assert rule.getId() > 0 : rule;
assert rule.getIPAddress() != null : rule; assert rule.getIPAddress() != null : rule;
assert rule.getIPAddressId() > 0 : rule; assert rule.getIPAddressId() > 0 : rule;

View File

@ -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();
}
}

View File

@ -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());
}
});
}
}

View File

@ -18,10 +18,13 @@
*/ */
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import java.util.Set; import java.util.Set;
import com.google.common.base.Strings;
import org.jclouds.cloudstack.domain.Cluster;
import org.jclouds.cloudstack.domain.Host; import org.jclouds.cloudstack.domain.Host;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -61,4 +64,29 @@ public class GlobalHostClientLiveTest extends BaseCloudStackClientLiveTest {
} }
} }
@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()));
}
} }

View File

@ -22,7 +22,9 @@ import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.options.CreateLoadBalancerRuleOptions;
import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions; import org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions;
import org.jclouds.cloudstack.options.UpdateLoadBalancerRuleOptions;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed; import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
@ -80,7 +82,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudStackAsyncClientTest<L
public void testCreateLoadBalancerRuleForPublicIP() throws SecurityException, NoSuchMethodException, IOException { public void testCreateLoadBalancerRuleForPublicIP() throws SecurityException, NoSuchMethodException, IOException {
Method method = LoadBalancerAsyncClient.class.getMethod("createLoadBalancerRuleForPublicIP", long.class, 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); HttpRequest httpRequest = processor.createRequest(method, 6, Algorithm.LEASTCONN, "tcp", 22, 22);
assertRequestLineEquals( assertRequestLineEquals(
@ -97,6 +99,22 @@ public class LoadBalancerAsyncClientTest extends BaseCloudStackAsyncClientTest<L
} }
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 { public void testDeleteLoadBalancerRule() throws SecurityException, NoSuchMethodException, IOException {
Method method = LoadBalancerAsyncClient.class.getMethod("deleteLoadBalancerRule", long.class); Method method = LoadBalancerAsyncClient.class.getMethod("deleteLoadBalancerRule", long.class);
HttpRequest httpRequest = processor.createRequest(method, 5); HttpRequest httpRequest = processor.createRequest(method, 5);

View File

@ -19,6 +19,8 @@
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import static com.google.common.collect.Iterables.find; 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.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -48,6 +50,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import javax.annotation.Nullable;
/** /**
* Tests behavior of {@code LoadBalancerClientLiveTest} * Tests behavior of {@code LoadBalancerClientLiveTest}
* *
@ -71,7 +75,16 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
prefix += "rule"; prefix += "rule";
try { try {
network = find(client.getNetworkClient().listNetworks(), 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) { } catch (NoSuchElementException e) {
networksDisabled = true; networksDisabled = true;
} }
@ -82,8 +95,8 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
return; return;
Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null; Long defaultTemplate = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network, vm = VirtualMachineClientLiveTest.createVirtualMachineInNetwork(network,
defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()), client, jobComplete, defaultTemplateOrPreferredInZone(defaultTemplate, client, network.getZoneId()),
virtualMachineRunning); client, jobComplete, virtualMachineRunning);
if (vm.getPassword() != null && !loginCredentials.hasPasswordOption()) if (vm.getPassword() != null && !loginCredentials.hasPasswordOption())
loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build(); loginCredentials = loginCredentials.toBuilder().password(vm.getPassword()).build();
} }

View File

@ -64,7 +64,7 @@ public class OfferingClientLiveTest extends BaseCloudStackClientLiveTest {
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
// This bug is present both in 2.2.8 and 2.2.12 // 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));
} }
} }
} }

View File

@ -31,6 +31,7 @@ import org.jclouds.cloudstack.domain.SecurityGroup;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.AccountInDomainOptions; import org.jclouds.cloudstack.options.AccountInDomainOptions;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListSecurityGroupsOptions; import org.jclouds.cloudstack.options.ListSecurityGroupsOptions;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.util.Strings2; import org.jclouds.util.Strings2;
@ -195,6 +196,23 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
assert group.getIngressRules() != null : group; 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") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {
if (vm != null) { if (vm != null) {

View File

@ -21,17 +21,17 @@ package org.jclouds.cloudstack.filters;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.net.URI; import java.net.URI;
import java.util.List;
import java.util.Map;
import org.jclouds.PropertiesBuilder; import org.jclouds.PropertiesBuilder;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.IntegrationTestAsyncClient;
import org.jclouds.http.IntegrationTestClient;
import org.jclouds.logging.config.NullLoggingModule; import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.BaseRestClientTest.MockModule;
import org.jclouds.rest.RequestSigner; import org.jclouds.rest.RequestSigner;
import org.jclouds.rest.RestContextBuilder; import org.jclouds.rest.RestContextBuilder;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec; import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.BaseRestClientTest.MockModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -48,8 +48,8 @@ import com.google.inject.Module;
@Test(groups = "unit", testName = "QuerySignerTest") @Test(groups = "unit", testName = "QuerySignerTest")
public class QuerySignerTest { public class QuerySignerTest {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public static final RestContextSpec<Map, List> DUMMY_SPEC = new RestContextSpec<Map, List>("cloudstack", public static final RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient> DUMMY_SPEC = new RestContextSpec<IntegrationTestClient, IntegrationTestAsyncClient>("cloudstack",
"http://localhost:8080/client/api", "2.2", "", "apiKey", "secretKey", Map.class, List.class, "http://localhost:8080/client/api", "2.2", "", "", "apiKey", "secretKey", IntegrationTestClient.class, IntegrationTestAsyncClient.class,
PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList.<Module> of(new MockModule(), PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList.<Module> of(new MockModule(),
new NullLoggingModule(), new AbstractModule() { new NullLoggingModule(), new AbstractModule() {
@Override @Override

View File

@ -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"));
}
}

View File

@ -22,8 +22,11 @@ import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builde
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.domainId; 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.id;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.name; 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.publicIPId;
import static org.jclouds.cloudstack.options.ListLoadBalancerRulesOptions.Builder.virtualMachineId; 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 static org.testng.Assert.assertEquals;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -99,4 +102,34 @@ public class ListLoadBalancerRulesOptionsTest {
ListLoadBalancerRulesOptions options = virtualMachineId(6); ListLoadBalancerRulesOptions options = virtualMachineId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("virtualmachineid")); 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"));
}
} }

View File

@ -18,9 +18,9 @@
*/ */
package org.jclouds.cloudstack.options; 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.accountInDomain;
import static org.jclouds.cloudstack.options.ListPortForwardingRulesOptions.Builder.domainId; 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 static org.testng.Assert.assertEquals;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -48,12 +48,12 @@ public class ListPortForwardingRulesOptionsTest {
} }
public void testName() { public void testName() {
ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().IPAddressId(9); ListPortForwardingRulesOptions options = new ListPortForwardingRulesOptions().ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid")); assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
} }
public void testNameStatic() { public void testNameStatic() {
ListPortForwardingRulesOptions options = IPAddressId(9); ListPortForwardingRulesOptions options = ipAddressId(9);
assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid")); assertEquals(ImmutableList.of("9"), options.buildQueryParameters().get("ipaddressid"));
} }

View File

@ -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);
}
}

View File

@ -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()
);
}
}

View File

@ -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()
);
}
}

View File

@ -61,10 +61,12 @@ public class ListPortForwardingRulesResponseTest extends BaseSetParserTest<PortF
public Set<PortForwardingRule> expected() { public Set<PortForwardingRule> expected() {
Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1"); Set<String> cidrs = ImmutableSet.of("0.0.0.0/1", "128.0.0.0/1");
return ImmutableSet.<PortForwardingRule> of( return ImmutableSet.<PortForwardingRule> of(
PortForwardingRule.builder().id(15).privatePort(22).protocol("tcp").publicPort(2022).virtualMachineId(3) PortForwardingRule.builder().id(15).privatePort(22).protocol(PortForwardingRule.Protocol.TCP)
.virtualMachineName("i-3-3-VM").IPAddressId(3).IPAddress("72.52.126.32").state("Active").CIDRs(cidrs).build(), .publicPort(2022).virtualMachineId(3).virtualMachineName("i-3-3-VM").IPAddressId(3)
PortForwardingRule.builder().id(18).privatePort(22).protocol("tcp").publicPort(22).virtualMachineId(89) .IPAddress("72.52.126.32").state(PortForwardingRule.State.ACTIVE).CIDRs(cidrs).build(),
.virtualMachineName("i-3-89-VM").IPAddressId(34).IPAddress("72.52.126.63").state("Active").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());
} }
} }

View File

@ -18,10 +18,7 @@
*/ */
package org.jclouds.cloudstack.predicates; package org.jclouds.cloudstack.predicates;
import static org.jclouds.cloudstack.predicates.NetworkPredicates.hasLoadBalancerService; import com.google.common.base.Predicate;
import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsPortForwarding;
import static org.jclouds.cloudstack.predicates.NetworkPredicates.supportsStaticNAT;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkService; import org.jclouds.cloudstack.domain.NetworkService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -30,6 +27,10 @@ import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; 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 * @author Adrian Cole
@ -93,4 +94,17 @@ public class NetworkPredicatesTest {
assert !hasLoadBalancerService().apply(network); 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));
}
} }

View File

@ -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; package org.jclouds.cloudstack.predicates;
import org.jclouds.cloudstack.domain.Template; import org.jclouds.cloudstack.domain.Template;

View File

@ -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; package org.jclouds.cloudstack.predicates;
import org.jclouds.cloudstack.domain.Account; import org.jclouds.cloudstack.domain.Account;

View File

@ -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; package org.jclouds.cloudstack.predicates;
import org.jclouds.cloudstack.domain.NetworkType; import org.jclouds.cloudstack.domain.NetworkType;

View File

@ -0,0 +1 @@
{ "createfirewallruleresponse" : {"jobid":2036,"id":2017} }

View File

@ -0,0 +1 @@
{ "createportforwardingruleresponse" : {"jobid":2035,"id":2015} }

View File

@ -0,0 +1 @@
{ "deletefirewallruleresponse" : {"jobid":2037} }

View File

@ -0,0 +1 @@
{ "deleteportforwardingruleresponse" : {"jobid":2038} }

View File

@ -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"} ] } }

View File

@ -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"} ] } }

View File

@ -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"} ] } }

View File

@ -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"}]
}}

View File

@ -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"} ] } }

View File

@ -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"} } }

View File

@ -35,7 +35,8 @@
<properties> <properties>
<test.cloudwatch.endpoint>https://monitoring.us-east-1.amazonaws.com</test.cloudwatch.endpoint> <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.identity>${test.aws.identity}</test.cloudwatch.identity>
<test.cloudwatch.credential>${test.aws.credential}</test.cloudwatch.credential> <test.cloudwatch.credential>${test.aws.credential}</test.cloudwatch.credential>
</properties> </properties>
@ -86,7 +87,8 @@
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<test.cloudwatch.endpoint>${test.cloudwatch.endpoint}</test.cloudwatch.endpoint> <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.identity>${test.cloudwatch.identity}</test.cloudwatch.identity>
<test.cloudwatch.credential>${test.cloudwatch.credential}</test.cloudwatch.credential> <test.cloudwatch.credential>${test.cloudwatch.credential}</test.cloudwatch.credential>
</systemPropertyVariables> </systemPropertyVariables>

Some files were not shown because too many files have changed in this diff Show More