Merge branch 'master' of github.com:jclouds/jclouds

* 'master' of github.com:jclouds/jclouds:
  added account features to cloudstack
  added more tests to Throwables
  Issue 538: removed redundant http tests which are not working due to test classpath issues
  loosened up thresholds on syncproxytest
  Issue 537: changed to bounded thread pool executor
  Changed Maven site URL to the jclouds Google Code site. Also using a fork of the WebDAV wagon to work around http://code.google.com/p/support/issues/detail?id=4786
  Changed project description to match extension -> driver change
  Merge branch 'master', remote branch 'origin'
  Clean up a comment on the blobstore2/blob function. For realsies.
  Clean up a comment on the blobstore2/blob function.
  Small enhancements to blobstore2_test.
  Update blobstore2 to have a convenience protocol for building blob payloads.
This commit is contained in:
Adrian Cole 2011-04-24 01:04:36 -07:00
commit 5288f12425
39 changed files with 1929 additions and 151 deletions

View File

@ -50,7 +50,7 @@ See http://code.google.com/p/jclouds for details."
domain.Blob domain.internal.BlobBuilderImpl options.PutOptions domain.Blob domain.internal.BlobBuilderImpl options.PutOptions
options.PutOptions$Builder options.PutOptions$Builder
options.CreateContainerOptions options.ListContainerOptions] options.CreateContainerOptions options.ListContainerOptions]
org.jclouds.io.Payloads [org.jclouds.io Payload Payloads payloads.StreamingPayload]
java.util.Arrays java.util.Arrays
[java.security DigestOutputStream MessageDigest] [java.security DigestOutputStream MessageDigest]
com.google.common.collect.ImmutableSet com.google.common.collect.ImmutableSet
@ -73,6 +73,39 @@ See http://code.google.com/p/jclouds for details."
(catch Exception e (catch Exception e
(JCECrypto.)))) (JCECrypto.))))
;;
;; Payload support for creating Blobs.
;;
(def ^{:doc "Type object for a Java primitive byte array, for use in the
PayloadSource protocol."
:private true}
byte-array-type (class (make-array Byte/TYPE 0)))
(defprotocol PayloadSource
"Various types can have PayloadSource extended onto them so that they are
easily coerced into a Payload."
(^Payload payload [arg] "Coerce arg into a Payload."))
(extend-protocol PayloadSource
Payload
(payload [p] p)
java.io.InputStream
(payload [is] (Payloads/newInputStreamPayload is))
byte-array-type
(payload [ba] (Payloads/newByteArrayPayload ba))
String
(payload [s] (Payloads/newStringPayload s))
java.io.File
(payload [f] (Payloads/newFilePayload f))
clojure.lang.IFn
;; This will let you pass a closure to payload that takes an OutputStream
;; as argument and writes to it when called from a StreamingPayload.
(payload [func]
(StreamingPayload. (reify org.jclouds.io.WriteTo
(writeTo [this output-stream]
(func output-stream))))))
(defn blobstore (defn blobstore
"Create a logged in context. "Create a logged in context.
Options for communication style Options for communication style
@ -278,7 +311,9 @@ Options can also be specified for extension modules
(.countBlobs blobstore container-name)) (.countBlobs blobstore container-name))
(defn blob (defn blob
"Create a new blob with the specified payload and options." "Create a new blob with the specified payload and options.
The payload argument can be anything accepted by the PayloadSource protocol."
([^String name & ([^String name &
{:keys [payload content-type content-length content-md5 calculate-md5 {:keys [payload content-type content-length content-md5 calculate-md5
content-disposition content-encoding content-language metadata]}] content-disposition content-encoding content-language metadata]}]
@ -286,7 +321,8 @@ Options can also be specified for extension modules
(not (and (nil? payload) calculate-md5))]} (not (and (nil? payload) calculate-md5))]}
(let [blob-builder (.name (BlobBuilderImpl. crypto-impl) name) (let [blob-builder (.name (BlobBuilderImpl. crypto-impl) name)
blob-builder (if payload blob-builder (if payload
(.payload blob-builder payload) (.payload blob-builder
(org.jclouds.blobstore2/payload payload))
(.forSigning blob-builder)) (.forSigning blob-builder))
blob-builder (if content-length ;; Special case, arg is prim. blob-builder (if content-length ;; Special case, arg is prim.
(.contentLength blob-builder content-length) (.contentLength blob-builder content-length)

View File

@ -22,7 +22,8 @@
(:use [clojure.test]) (:use [clojure.test])
(:import [org.jclouds.blobstore BlobStoreContextFactory] (:import [org.jclouds.blobstore BlobStoreContextFactory]
[org.jclouds.crypto CryptoStreams] [org.jclouds.crypto CryptoStreams]
[java.io ByteArrayOutputStream] [java.io ByteArrayInputStream ByteArrayOutputStream
StringBufferInputStream]
[org.jclouds.util Strings2])) [org.jclouds.util Strings2]))
(defn clean-stub-fixture (defn clean-stub-fixture
@ -157,4 +158,37 @@
(is (= (seq (.. a-blob (getPayload) (getContentMetadata) (getContentMD5))) (is (= (seq (.. a-blob (getPayload) (getContentMetadata) (getContentMD5)))
(seq (CryptoStreams/md5 (.getBytes "test-payload"))))))) (seq (CryptoStreams/md5 (.getBytes "test-payload")))))))
(deftest payload-protocol-test
(is (instance? org.jclouds.io.Payload (payload "test")))
(is (blob "blob1" :payload (payload "blob1")))
(is (create-container *blobstore* "container"))
(is (= "blob1"
(do
(put-blob *blobstore* "container"
(blob "blob1"
:payload "blob1"))
(Strings2/toStringAndClose (get-blob-stream *blobstore*
"container" "blob1")))))
(is (= "blob2"
(do
(put-blob *blobstore* "container"
(blob "blob2"
:payload (StringBufferInputStream. "blob2")))
(Strings2/toStringAndClose (get-blob-stream *blobstore*
"container" "blob2")))))
(is (= "blob3"
(do
(put-blob *blobstore* "container"
(blob "blob3"
:payload (.getBytes "blob3")))
(Strings2/toStringAndClose (get-blob-stream *blobstore*
"container" "blob3")))))
(is (= "blob4"
(do
(put-blob *blobstore* "container"
(blob "blob4"
:payload #(.write % (.getBytes "blob4"))))
(Strings2/toStringAndClose (get-blob-stream *blobstore*
"container" "blob4"))))))
;; TODO: more tests involving blob-specific functions ;; TODO: more tests involving blob-specific functions

View File

@ -25,8 +25,8 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.jclouds.concurrent.DynamicExecutors;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.testng.annotations.AfterTest; import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
@ -44,7 +44,7 @@ public abstract class PerformanceTest {
@BeforeTest @BeforeTest
public void setupExecutorService() { public void setupExecutorService() {
exec = Executors.newCachedThreadPool(); exec = DynamicExecutors.newScalingThreadPool(1, THREAD_COUNT, 1000);
} }
@AfterTest @AfterTest

View File

@ -46,15 +46,15 @@ import com.google.inject.Provides;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit", sequential = true) @Test(groups = "unit", singleThreaded = true)
public class SyncProxyTest { public class SyncProxyTest {
@Test @Test
void testConvertNanos() { void testConvertNanos() {
assertEquals(SyncProxy.convertToNanos(Sync.class.getAnnotation(Timeout.class)), 30000000); assertEquals(SyncProxy.convertToNanos(Sync.class.getAnnotation(Timeout.class)), 40000000);
} }
@Timeout(duration = 30, timeUnit = TimeUnit.MILLISECONDS) @Timeout(duration = 40, timeUnit = TimeUnit.MILLISECONDS)
private static interface Sync { private static interface Sync {
String getString(); String getString();
@ -69,10 +69,10 @@ public class SyncProxyTest {
String take20Milliseconds(); String take20Milliseconds();
String take100MillisecondsAndTimeout(); String take200MillisecondsAndTimeout();
@Timeout(duration = 300, timeUnit = TimeUnit.MILLISECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.MILLISECONDS)
String take100MillisecondsAndOverride(); String take200MillisecondsAndOverride();
} }
@ -137,12 +137,12 @@ public class SyncProxyTest {
}), executorService); }), executorService);
} }
public ListenableFuture<String> take100MillisecondsAndTimeout() { public ListenableFuture<String> take200MillisecondsAndTimeout() {
return Futures.makeListenable(executorService.submit(new Callable<String>() { return Futures.makeListenable(executorService.submit(new Callable<String>() {
public String call() { public String call() {
try { try {
Thread.sleep(100); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -152,8 +152,8 @@ public class SyncProxyTest {
}), executorService); }), executorService);
} }
public ListenableFuture<String> take100MillisecondsAndOverride() { public ListenableFuture<String> take200MillisecondsAndOverride() {
return take100MillisecondsAndTimeout(); return take200MillisecondsAndTimeout();
} }
} }
@ -164,6 +164,8 @@ public class SyncProxyTest {
public void setUp() throws IllegalArgumentException, SecurityException, NoSuchMethodException { public void setUp() throws IllegalArgumentException, SecurityException, NoSuchMethodException {
sync = SyncProxy.proxy(Sync.class, new SyncProxy(Sync.class, new Async(), sync = SyncProxy.proxy(Sync.class, new SyncProxy(Sync.class, new Async(),
new ConcurrentHashMap<ClassMethodArgs, Object>(), ImmutableMap.<Class<?>, Class<?>> of())); new ConcurrentHashMap<ClassMethodArgs, Object>(), ImmutableMap.<Class<?>, Class<?>> of()));
// just to warm up
sync.string();
} }
@Test @Test
@ -184,14 +186,13 @@ public class SyncProxyTest {
} }
@Test(expectedExceptions = RuntimeException.class) @Test(expectedExceptions = RuntimeException.class)
public void testTake100MillisecondsAndTimeout() { public void testTake200MillisecondsAndTimeout() {
assertEquals(sync.take100MillisecondsAndTimeout(), "foo"); assertEquals(sync.take200MillisecondsAndTimeout(), "foo");
} }
@Test @Test
public void testTake100MillisecondsAndOverride() { public void testTake200MillisecondsAndOverride() {
assertEquals(sync.take100MillisecondsAndOverride(), "foo"); assertEquals(sync.take200MillisecondsAndOverride(), "foo");
} }
@Test @Test

View File

@ -24,6 +24,8 @@ import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
import static org.jclouds.util.Throwables2.returnFirstExceptionIfInListOrThrowStandardExceptionOrCause; import static org.jclouds.util.Throwables2.returnFirstExceptionIfInListOrThrowStandardExceptionOrCause;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.SocketException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpCommand;
@ -51,6 +53,11 @@ public class Throwables2Test {
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex); assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex);
} }
public void testGetFirstThrowableOfTypeSubclass() {
SocketException aex = createMock(SocketException.class);
assertEquals(getFirstThrowableOfType(aex, IOException.class), aex);
}
public void testGetFirstThrowableOfTypeOuter() { public void testGetFirstThrowableOfTypeOuter() {
AuthorizationException aex = createMock(AuthorizationException.class); AuthorizationException aex = createMock(AuthorizationException.class);
assertEquals(getFirstThrowableOfType(aex, AuthorizationException.class), aex); assertEquals(getFirstThrowableOfType(aex, AuthorizationException.class), aex);

View File

@ -1,51 +0,0 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.enterprise.config;
import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT;
import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import java.util.Properties;
import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest;
import com.google.inject.Module;
/**
* Tests the functionality of the {@link EnterpriseConfigurationModule}
*
* @author Adrian Cole
*/
public class EnterpriseConfigurationModuleTest extends BaseHttpCommandExecutorServiceIntegrationTest {
protected Module createConnectionModule() {
return new EnterpriseConfigurationModule();
}
protected void addConnectionProperties(Properties props) {
props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, 50 + "");
props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_HOST, 50 + "");
// IO workers not used in this executor
props.setProperty(PROPERTY_IO_WORKER_THREADS, 0 + "");
props.setProperty(PROPERTY_USER_THREADS, 5 + "");
}
}

View File

@ -30,7 +30,7 @@
</parent> </parent>
<artifactId>jclouds-drivers-project</artifactId> <artifactId>jclouds-drivers-project</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>jclouds extensions project</name> <name>jclouds drivers project</name>
<modules> <modules>
<module>gae</module> <module>gae</module>
<module>apachehc</module> <module>apachehc</module>

View File

@ -100,9 +100,8 @@
<url>https://oss.sonatype.org/content/repositories/snapshots</url> <url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository> </snapshotRepository>
<site> <site>
<id>website</id> <id>jclouds-googlecode-site</id>
<name>website</name> <url>dav+https://jclouds.googlecode.com/svn/maven-sites/${project.version}</url>
<url>file://${basedir}/target/dist/site/jclouds-testing/</url>
</site> </site>
</distributionManagement> </distributionManagement>
@ -501,7 +500,17 @@ pageTracker._trackPageview();
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-site-plugin</artifactId> <artifactId>maven-site-plugin</artifactId>
<version>2.2</version> <configuration>
<stagingRepositoryId>${project.distributionManagement.site.id}</stagingRepositoryId>
<stagingSiteURL>${project.distributionManagement.site.url}</stagingSiteURL>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-webdav-jackrabbit</artifactId>
<version>1.0-beta-8-WAGON-319</version>
</dependency>
</dependencies>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-deploy-plugin</artifactId> <artifactId>maven-deploy-plugin</artifactId>
@ -681,6 +690,16 @@ pageTracker._trackPageview();
<missing>${basedir}</missing> <missing>${basedir}</missing>
</file> </file>
</activation> </activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting> <reporting>
<plugins> <plugins>
<plugin> <plugin>
@ -766,19 +785,6 @@ pageTracker._trackPageview();
</file> </file>
</activation> </activation>
<build> <build>
<plugins>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<executions>
<execution>
<id>attach-descriptor</id>
<goals>
<goal>attach-descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin> <plugin>

View File

@ -18,6 +18,7 @@
*/ */
package org.jclouds.cloudstack; package org.jclouds.cloudstack;
import org.jclouds.cloudstack.features.AccountAsyncClient;
import org.jclouds.cloudstack.features.AddressAsyncClient; import org.jclouds.cloudstack.features.AddressAsyncClient;
import org.jclouds.cloudstack.features.AsyncJobAsyncClient; import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
import org.jclouds.cloudstack.features.ConfigurationAsyncClient; import org.jclouds.cloudstack.features.ConfigurationAsyncClient;
@ -127,4 +128,10 @@ public interface CloudStackAsyncClient {
*/ */
@Delegate @Delegate
ConfigurationAsyncClient getConfigurationClient(); ConfigurationAsyncClient getConfigurationClient();
/**
* Provides asynchronous access to Account features.
*/
@Delegate
AccountAsyncClient getAccountClient();
} }

View File

@ -20,6 +20,7 @@ package org.jclouds.cloudstack;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressClient; import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobClient; import org.jclouds.cloudstack.features.AsyncJobClient;
import org.jclouds.cloudstack.features.ConfigurationClient; import org.jclouds.cloudstack.features.ConfigurationClient;
@ -130,4 +131,10 @@ public interface CloudStackClient {
*/ */
@Delegate @Delegate
ConfigurationClient getConfigurationClient(); ConfigurationClient getConfigurationClient();
/**
* Provides synchronous access to Account features.
*/
@Delegate
AccountClient getAccountClient();
} }

View File

@ -18,10 +18,19 @@
*/ */
package org.jclouds.cloudstack.config; package org.jclouds.cloudstack.config;
import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.cloudstack.CloudStackAsyncClient; import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.domain.Account.State;
import org.jclouds.cloudstack.features.AccountAsyncClient;
import org.jclouds.cloudstack.features.AccountClient;
import org.jclouds.cloudstack.features.AddressAsyncClient; import org.jclouds.cloudstack.features.AddressAsyncClient;
import org.jclouds.cloudstack.features.AddressClient; import org.jclouds.cloudstack.features.AddressClient;
import org.jclouds.cloudstack.features.AsyncJobAsyncClient; import org.jclouds.cloudstack.features.AsyncJobAsyncClient;
@ -64,6 +73,14 @@ import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.SerializedName;
import com.google.inject.TypeLiteral;
/** /**
* Configures the cloudstack connection. * Configures the cloudstack connection.
@ -89,12 +106,98 @@ 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(AccountClient.class, AccountAsyncClient.class)//
.build(); .build();
public CloudStackRestClientModule() { public CloudStackRestClientModule() {
super(CloudStackClient.class, CloudStackAsyncClient.class, DELEGATE_MAP); super(CloudStackClient.class, CloudStackAsyncClient.class, DELEGATE_MAP);
} }
@Singleton
public static class BreakGenericSetAdapter implements JsonSerializer<Account>, JsonDeserializer<Account> {
public JsonElement serialize(Account src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
public Account deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return apply(context.<AccountInternal> deserialize(json, AccountInternal.class));
}
public Account apply(AccountInternal in) {
return Account.builder().id(in.id).type(in.type).domain(in.domain).domainId(in.domainId).IPsAvailable(
nullIfUnlimited(in.IPsAvailable)).IPLimit(nullIfUnlimited(in.IPLimit)).IPs(in.IPs).cleanupRequired(
in.cleanupRequired).name(in.name).receivedBytes(in.receivedBytes).sentBytes(in.sentBytes)
.snapshotsAvailable(nullIfUnlimited(in.snapshotsAvailable)).snapshotLimit(
nullIfUnlimited(in.snapshotLimit)).snapshots(in.snapshots).state(in.state)
.templatesAvailable(nullIfUnlimited(in.templatesAvailable)).templateLimit(
nullIfUnlimited(in.templateLimit)).templates(in.templates).VMsAvailable(
nullIfUnlimited(in.VMsAvailable)).VMLimit(nullIfUnlimited(in.VMLimit)).VMsRunning(
in.VMsRunning).VMsStopped(in.VMsStopped).VMs(in.VMs).volumesAvailable(
nullIfUnlimited(in.volumesAvailable)).volumeLimit(nullIfUnlimited(in.volumeLimit)).volumes(
in.volumes).users(in.users).build();
}
static final class AccountInternal {
private long id;
@SerializedName("accounttype")
private Account.Type type;
private String domain;
@SerializedName("domainid")
private long domainId;
@SerializedName("ipavailable")
private String IPsAvailable;
@SerializedName("iplimit")
private String IPLimit;
@SerializedName("iptotal")
private long IPs;
@SerializedName("iscleanuprequired")
private boolean cleanupRequired;
private String name;
@SerializedName("receivedbytes")
private long receivedBytes;
@SerializedName("sentBytes")
private long sentBytes;
@SerializedName("snapshotavailable")
private String snapshotsAvailable;
@SerializedName("snapshotlimit")
private String snapshotLimit;
@SerializedName("snapshottotal")
private long snapshots;
@SerializedName("state")
private State state;
@SerializedName("templateavailable")
private String templatesAvailable;
@SerializedName("templatelimit")
private String templateLimit;
@SerializedName("templatetotal")
private long templates;
@SerializedName("vmavailable")
private String VMsAvailable;
@SerializedName("vmlimit")
private String VMLimit;
@SerializedName("vmrunning")
private long VMsRunning;
@SerializedName("vmstopped")
private long VMsStopped;
@SerializedName("vmtotal")
private long VMs;
@SerializedName("volumeavailable")
private String volumesAvailable;
@SerializedName("volumelimit")
private String volumeLimit;
@SerializedName("volumetotal")
private long volumes;
@SerializedName("user")
private Set<User> users;
}
private static Long nullIfUnlimited(String in) {
return in == null || "Unlimited".equals(in) ? null : new Long(in);
}
}
@Override @Override
protected void configure() { protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class); bind(DateAdapter.class).to(Iso8601DateAdapter.class);
@ -106,6 +209,8 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
} }
}); });
bind(new TypeLiteral<Map<Type, Object>>() {
}).toInstance(ImmutableMap.<Type, Object> of(Account.class, new BreakGenericSetAdapter()));
super.configure(); super.configure();
} }

View File

@ -0,0 +1,643 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.CaseFormat;
import com.google.common.base.Function;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
/**
*
* @author Adrian Cole
*/
public class Account extends ForwardingSet<User> implements Comparable<Account> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id;
private Type type;
private String domain;
private long domainId;
private Long IPsAvailable;
private Long IPLimit;
private long IPs;
private boolean cleanupRequired;
private String name;
private long receivedBytes;
private long sentBytes;
private Long snapshotsAvailable;
private Long snapshotLimit;
private long snapshots;
private State state;
private Long templatesAvailable;
private Long templateLimit;
private long templates;
private Long VMsAvailable;
private Long VMLimit;
private long VMsRunning;
private long VMsStopped;
private long VMs;
private Long volumesAvailable;
private Long volumeLimit;
private long volumes;
private Set<User> users = ImmutableSet.of();
public Builder id(long id) {
this.id = id;
return this;
}
public Builder type(Type type) {
this.type = type;
return this;
}
public Builder domain(String domain) {
this.domain = domain;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder IPsAvailable(Long IPsAvailable) {
this.IPsAvailable = IPsAvailable;
return this;
}
public Builder IPLimit(Long IPLimit) {
this.IPLimit = IPLimit;
return this;
}
public Builder IPs(long IPs) {
this.IPs = IPs;
return this;
}
public Builder cleanupRequired(boolean cleanupRequired) {
this.cleanupRequired = cleanupRequired;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder receivedBytes(long receivedBytes) {
this.receivedBytes = receivedBytes;
return this;
}
public Builder sentBytes(long sentBytes) {
this.sentBytes = sentBytes;
return this;
}
public Builder snapshotsAvailable(Long snapshotsAvailable) {
this.snapshotsAvailable = snapshotsAvailable;
return this;
}
public Builder snapshotLimit(Long snapshotLimit) {
this.snapshotLimit = snapshotLimit;
return this;
}
public Builder snapshots(long snapshots) {
this.snapshots = snapshots;
return this;
}
public Builder state(State state) {
this.state = state;
return this;
}
public Builder templatesAvailable(Long templatesAvailable) {
this.templatesAvailable = templatesAvailable;
return this;
}
public Builder templateLimit(Long templateLimit) {
this.templateLimit = templateLimit;
return this;
}
public Builder templates(long templates) {
this.templates = templates;
return this;
}
public Builder VMsAvailable(Long VMsAvailable) {
this.VMsAvailable = VMsAvailable;
return this;
}
public Builder VMLimit(Long VMLimit) {
this.VMLimit = VMLimit;
return this;
}
public Builder VMsRunning(long VMsRunning) {
this.VMsRunning = VMsRunning;
return this;
}
public Builder VMsStopped(long VMsStopped) {
this.VMsStopped = VMsStopped;
return this;
}
public Builder VMs(long VMs) {
this.VMs = VMs;
return this;
}
public Builder volumesAvailable(Long volumesAvailable) {
this.volumesAvailable = volumesAvailable;
return this;
}
public Builder volumeLimit(Long volumeLimit) {
this.volumeLimit = volumeLimit;
return this;
}
public Builder volumes(long volumes) {
this.volumes = volumes;
return this;
}
public Builder users(Set<User> users) {
this.users = ImmutableSet.copyOf(checkNotNull(users, "users"));
return this;
}
public Account build() {
return new Account(id, type, domain, domainId, IPsAvailable, IPLimit, IPs, cleanupRequired, name,
receivedBytes, sentBytes, snapshotsAvailable, snapshotLimit, snapshots, state, templatesAvailable,
templateLimit, templates, VMsAvailable, VMLimit, VMsRunning, VMsStopped, VMs, volumesAvailable,
volumeLimit, volumes, users);
}
}
public static enum State {
ENABLED, DISABLED, LOCKED, UNRECOGNIZED;
@Override
public String toString() {
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
}
public static State fromValue(String state) {
try {
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
public static enum Type {
/**
* full API access. This is typically a service administrator or code that executes with
* complete trust in the service operator's environment.
*/
ADMIN(1),
/**
* full API access within a domain. This is the most privileged user that a given customer
* has. This may be a reseller for the service provider.
*/
DOMAIN_ADMIN(2),
// TODO get code for read-only user.
// /**
// * API access limited to viewing most entities. No access is given to create or update those
// * entities. This may be useful for monitoring programs in the service operator's
// environment.
// */
// READ_ONLY_ADMIN(?)
/**
* API access for all the resources associated with their account. There may be many users in
* a domain, many domains in a deployment, and many users in a deployment. This is typically
* the end user
*/
USER(0), UNRECOGNIZED(Integer.MAX_VALUE);
private int code;
private static final Map<Integer, Type> INDEX = Maps.uniqueIndex(ImmutableSet.copyOf(Type.values()),
new Function<Type, Integer>() {
@Override
public Integer apply(Type input) {
return input.code;
}
});
Type(int code) {
this.code = code;
}
@Override
public String toString() {
return name();
}
public static Type fromValue(String type) {
Integer code = new Integer(checkNotNull(type, "type"));
return INDEX.containsKey(code) ? INDEX.get(code) : UNRECOGNIZED;
}
}
private long id;
private Type type;
private String domain;
private long domainId;
private Long IPsAvailable;
private Long IPLimit;
private long IPs;
private boolean cleanupRequired;
private String name;
private long receivedBytes;
private long sentBytes;
private Long snapshotsAvailable;
private Long snapshotLimit;
private long snapshots;
private State state;
private Long templatesAvailable;
private Long templateLimit;
private long templates;
private Long VMsAvailable;
private Long VMLimit;
private long VMsRunning;
private long VMsStopped;
private long VMs;
private Long volumesAvailable;
private Long volumeLimit;
private long volumes;
private Set<User> users;
public Account(long id, Type type, String domain, long domainId, Long IPsAvailable, Long IPLimit, long iPs,
boolean cleanupRequired, String name, long receivedBytes, long sentBytes, Long snapshotsAvailable,
Long snapshotLimit, long snapshots, org.jclouds.cloudstack.domain.Account.State state,
Long templatesAvailable, Long templateLimit, long templates, Long VMsAvailable, Long VMLimit,
long vMsRunning, long vMsStopped, long vMs, Long volumesAvailable, Long volumeLimit, long volumes,
Set<User> users) {
this.id = id;
this.type = type;
this.domain = domain;
this.domainId = domainId;
this.IPsAvailable = IPsAvailable;
this.IPLimit = IPLimit;
this.IPs = iPs;
this.cleanupRequired = cleanupRequired;
this.name = name;
this.receivedBytes = receivedBytes;
this.sentBytes = sentBytes;
this.snapshotsAvailable = snapshotsAvailable;
this.snapshotLimit = snapshotLimit;
this.snapshots = snapshots;
this.state = state;
this.templatesAvailable = templatesAvailable;
this.templateLimit = templateLimit;
this.templates = templates;
this.VMsAvailable = VMsAvailable;
this.VMLimit = VMLimit;
this.VMsRunning = vMsRunning;
this.VMsStopped = vMsStopped;
this.VMs = vMs;
this.volumesAvailable = volumesAvailable;
this.volumeLimit = volumeLimit;
this.volumes = volumes;
this.users = ImmutableSet.copyOf(checkNotNull(users, "users"));
}
/**
* present only for serializer
*
*/
Account() {
}
/**
*
* @return the id of the account
*/
public long getId() {
return id;
}
/**
*
* @return the name of the account
*/
public String getName() {
return name;
}
/**
*
* @return account type (admin, domain-admin, user)
*/
public Type getType() {
return type;
}
/**
*
* @return name of the Domain the account belongs to
*/
public String getDomain() {
return domain;
}
/**
*
* @return id of the Domain the account belongs to
*/
public long getDomainId() {
return domainId;
}
/**
*
* @return true if the account requires cleanup
*/
public boolean isCleanupRequired() {
return cleanupRequired;
}
/**
*
* @return the list of users associated with account
*/
public Set<User> getUsers() {
return users;
}
/**
*
* @return the total number of public ip addresses available for this account to acquire, or null
* if unlimited
*/
@Nullable
public Long getIPsAvailable() {
return IPsAvailable;
}
/**
*
* @return the total number of public ip addresses this account can acquire, or null if unlimited
*/
@Nullable
public Long getIPLimit() {
return IPLimit;
}
/**
*
* @return the total number of public ip addresses allocated for this account
*/
public long getIPs() {
return IPs;
}
/**
*
* @return the total number of network traffic bytes received
*/
public long getReceivedBytes() {
return receivedBytes;
}
/**
*
* @return the total number of network traffic bytes sent
*/
public long getSentBytes() {
return sentBytes;
}
/**
*
* @return the total number of snapshots available for this account, or null if unlimited
*/
@Nullable
public Long getSnapshotsAvailable() {
return snapshotsAvailable;
}
/**
*
* @return the total number of snapshots which can be stored by this account, or null if
* unlimited
*/
@Nullable
public Long getSnapshotLimit() {
return snapshotLimit;
}
/**
*
* @return the total number of snapshots stored by this account
*/
public long getSnapshots() {
return snapshots;
}
/**
*
* @return the state of the account
*/
public State getState() {
return state;
}
/**
*
* @return the total number of templates available to be created by this account, or null if
* unlimited
*/
@Nullable
public Long getTemplatesAvailable() {
return templatesAvailable;
}
/**
*
* @return the total number of templates which can be created by this account, or null if
* unlimited
*/
@Nullable
public Long getTemplateLimit() {
return templateLimit;
}
/**
*
* @return the total number of templates which have been created by this account
*/
public long getTemplates() {
return templates;
}
/**
*
* @return the total number of virtual machines available for this account to acquire, or null if
* unlimited
*/
@Nullable
public Long getVMsAvailable() {
return VMsAvailable;
}
/**
*
* @return the total number of virtual machines that can be deployed by this account, or null if
* unlimited
*/
@Nullable
public Long getVMLimit() {
return VMLimit;
}
/**
*
* @return the total number of virtual machines running for this account
*/
public long getVMsRunning() {
return VMsRunning;
}
/**
*
* @return the total number of virtual machines stopped for this account
*/
public long getVMsStopped() {
return VMsStopped;
}
/**
*
* @return the total number of virtual machines deployed by this account
*/
public long getVMs() {
return VMs;
}
/**
*
* @return the total volume available for this account, or null if unlimited
*/
@Nullable
public Long getVolumesAvailable() {
return volumesAvailable;
}
/**
*
* @return the total volume which can be used by this account, or null if unlimited
*/
@Nullable
public Long getVolumeLimit() {
return volumeLimit;
}
/**
*
* @return the total volume being used by this account
*/
public long getVolumes() {
return volumes;
}
@Override
public int compareTo(Account arg0) {
return new Long(id).compareTo(arg0.getId());
}
@Override
public String toString() {
return String
.format(
"[id=%s, name=%s, type=%s, state=%s, domain=%s, domainId=%s, cleanupRequired=%s, sentBytes=%s, receivedBytes=%s, IPs=%s, IPsAvailable=%s, IPLimit=%s, VMs=%s, VMsAvailable=%s, VMsRunning=%s, VMsStopped=%s, VMLimit=%s, snapshots=%s, snapshotLimit=%s, snapshotsAvailable=%s, templateLimit=%s, templates=%s, templatesAvailable=%s, volumes=%s, volumeLimit=%s, volumesAvailable=%s, users=%s]",
id, name, type, state, domain, domainId, cleanupRequired, sentBytes, receivedBytes, IPs,
IPsAvailable, IPLimit, VMs, VMsAvailable, VMsRunning, VMsStopped, VMLimit, snapshots,
snapshotLimit, snapshotsAvailable, templateLimit, templates, templatesAvailable, volumes,
volumeLimit, volumesAvailable, users);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (domainId ^ (domainId >>> 32));
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Account other = (Account) obj;
if (domainId != other.domainId)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
protected Set<User> delegate() {
return users;
}
}

View File

@ -37,24 +37,16 @@ public class Template implements Comparable<Template> {
public static class Builder { public static class Builder {
private long id; private long id;
@SerializedName("displaytext")
private String displayText; private String displayText;
private String domain; private String domain;
@SerializedName("domainid")
private long domainId; private long domainId;
private String account; private String account;
@SerializedName("accountid")
private long accountId; private long accountId;
@SerializedName("zonename")
private String zone; private String zone;
@SerializedName("zoneid")
private long zoneId; private long zoneId;
@SerializedName("ostypename")
private String OSType; private String OSType;
@SerializedName("ostypeid")
private long OSTypeId; private long OSTypeId;
private String name; private String name;
@SerializedName("templatetype")
private Type type; private Type type;
private String status; private String status;
private Format format; private Format format;
@ -62,24 +54,14 @@ public class Template implements Comparable<Template> {
private Long size; private Long size;
private Date created; private Date created;
private Date removed; private Date removed;
@SerializedName("crossZones")
private boolean crossZones; private boolean crossZones;
@SerializedName("bootable")
private boolean bootable; private boolean bootable;
@SerializedName("isextractable")
private boolean extractable; private boolean extractable;
@SerializedName("isfeatured")
private boolean featured; private boolean featured;
@SerializedName("ispublic")
private boolean isPublic; private boolean isPublic;
@SerializedName("isready")
private boolean ready; private boolean ready;
@SerializedName("passwordenabled")
private boolean passwordEnabled; private boolean passwordEnabled;
@Nullable
@SerializedName("jobid")
private Long jobId; private Long jobId;
@SerializedName("jobstatus")
private String jobStatus; private String jobStatus;
public Builder id(long id) { public Builder id(long id) {

View File

@ -0,0 +1,336 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.domain;
import java.util.Date;
import org.jclouds.cloudstack.domain.Account.Type;
import com.google.gson.annotations.SerializedName;
/**
*
* @author Adrian Cole
*/
public class User implements Comparable<User> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private long id;
private String name;
private String firstName;
private String lastName;
private String email;
private Date created;
private String state;
private String account;
private Account.Type accountType;
private String domain;
private long domainId;
private String timeZone;
private String apiKey;
private String secretKey;
public Builder id(long id) {
this.id = id;
return this;
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder created(Date created) {
this.created = created;
return this;
}
public Builder state(String state) {
this.state = state;
return this;
}
public Builder account(String account) {
this.account = account;
return this;
}
public Builder accountType(Account.Type accountType) {
this.accountType = accountType;
return this;
}
public Builder domain(String domain) {
this.domain = domain;
return this;
}
public Builder domainId(long domainId) {
this.domainId = domainId;
return this;
}
public Builder timeZone(String timeZone) {
this.timeZone = timeZone;
return this;
}
public Builder apiKey(String apiKey) {
this.apiKey = apiKey;
return this;
}
public Builder secretKey(String secretKey) {
this.secretKey = secretKey;
return this;
}
public User build() {
return new User(id, name, firstName, lastName, email, created, state, account, accountType, domain, domainId,
timeZone, apiKey, secretKey);
}
}
/**
* present only for serializer
*
*/
User() {
}
private long id;
@SerializedName("username")
private String name;
@SerializedName("firstname")
private String firstName;
@SerializedName("lastname")
private String lastName;
private String email;
private Date created;
private String state;
private String account;
@SerializedName("accounttype")
private Account.Type accountType;
private String domain;
@SerializedName("domainid")
private long domainId;
@SerializedName("timezone")
private String timeZone;
@SerializedName("apikey")
private String apiKey;
@SerializedName("secretkey")
private String secretKey;
public User(long id, String name, String firstname, String lastname, String email, Date created, String state,
String account, Type accountType, String domain, long domainId, String timeZone, String apiKey,
String secretKey) {
this.id = id;
this.name = name;
this.firstName = firstname;
this.lastName = lastname;
this.email = email;
this.created = created;
this.state = state;
this.account = account;
this.accountType = accountType;
this.domain = domain;
this.domainId = domainId;
this.timeZone = timeZone;
this.apiKey = apiKey;
this.secretKey = secretKey;
}
/**
*
* @return the user ID
*/
public long getId() {
return id;
}
/**
*
* @return the user name
*/
public String getName() {
return name;
}
/**
*
* @return the user firstname
*/
public String getFirstName() {
return firstName;
}
/**
*
* @return the user lastname
*/
public String getLastName() {
return lastName;
}
/**
*
* @return the user email address
*/
public String getEmail() {
return email;
}
/**
*
* @return the date and time the user account was created
*/
public Date getCreated() {
return created;
}
/**
*
* @return the user state
*/
public String getState() {
return state;
}
/**
*
* @return the account name of the user
*/
public String getAccount() {
return account;
}
/**
*
* @return the account type of the user
*/
public Account.Type getAccountType() {
return accountType;
}
/**
*
* @return the domain name of the user
*/
public String getDomain() {
return domain;
}
/**
*
* @return the domain ID of the user
*/
public long getDomainId() {
return domainId;
}
/**
*
* @return the timezone user was created in
*/
public String getTimeZone() {
return timeZone;
}
/**
*
* @return the api key of the user
*/
public String getApiKey() {
return apiKey;
}
/**
*
* @return the secret key of the user
*/
public String getSecretKey() {
return secretKey;
}
@Override
public int compareTo(User arg0) {
return new Long(id).compareTo(arg0.getId());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((account == null) ? 0 : account.hashCode());
result = prime * result + (int) (domainId ^ (domainId >>> 32));
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (account == null) {
if (other.account != null)
return false;
} else if (!account.equals(other.account))
return false;
if (domainId != other.domainId)
return false;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return String
.format(
"[id=%s, name=%s, state=%s, created=%s, account=%s, accountType=%s, domain=%s, domainId=%s, email=%s, firstName=%s, lastName=%s, apiKey=%s, secretKey=%s, timeZone=%s]",
id, name, state, created, account, accountType, domain, domainId, email, firstName, lastName,
apiKey, secretKey, timeZone);
}
}

View File

@ -0,0 +1,71 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.features;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.filters.QuerySigner;
import org.jclouds.cloudstack.options.ListAccountsOptions;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.Unwrap;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to cloudstack via their REST API.
* <p/>
*
* @see AccountClient
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@RequestFilters(QuerySigner.class)
@QueryParams(keys = "response", values = "json")
public interface AccountAsyncClient {
/**
* @see AccountClient#listAccounts
*/
@GET
@QueryParams(keys = "command", values = "listAccounts")
@Unwrap(depth = 2)
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Account>> listAccounts(ListAccountsOptions... options);
/**
* @see AccountClient#getAccount
*/
@GET
@QueryParams(keys = "command", values = "listAccounts")
@Unwrap(depth = 3, edgeCollection = Set.class)
@Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Account> getAccount(@QueryParam("id") long id);
}

View File

@ -0,0 +1,54 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.options.ListAccountsOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides synchronous access to CloudStack Account features.
* <p/>
*
* @see <a href="http://download.cloud.com/releases/2.2.0/api/TOC_User.html" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface AccountClient {
/**
* Lists Accounts
*
* @param options
* if present, how to constrain the list.
* @return Accounts matching query, or empty set, if no Accounts are found
*/
Set<Account> listAccounts(ListAccountsOptions... options);
/**
* get a specific Account by id
*
* @param id
* Account to get
* @return Account or null if not found
*/
Account getAccount(long id);
}

View File

@ -0,0 +1,153 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.options;
import com.google.common.collect.ImmutableSet;
/**
* Options used to control what account information is returned
*
* @see <a href="http://download.cloud.com/releases/2.2.0/api/user/listAccounts.html" />
* @author Adrian Cole
*/
public class ListAccountsOptions extends AccountInDomainOptions {
public static final ListAccountsOptions NONE = new ListAccountsOptions();
/**
* @param id
* list account by account ID
*/
public ListAccountsOptions id(long id) {
this.queryParameters.replaceValues("id", ImmutableSet.of(id + ""));
return this;
}
/**
* @param name
* list account by account name
*/
public ListAccountsOptions name(String name) {
this.queryParameters.replaceValues("name", ImmutableSet.of(name));
return this;
}
/**
* @param state
* list accounts by state. Valid states are enabled, disabled, and locked.
*/
public ListAccountsOptions state(String state) {
this.queryParameters.replaceValues("state", ImmutableSet.of(state));
return this;
}
/**
* @param cleanupRequired
* list accounts by cleanuprequred attribute
*/
public ListAccountsOptions cleanupRequired(boolean cleanupRequired) {
this.queryParameters.replaceValues("iscleanuprequired", ImmutableSet.of(cleanupRequired + ""));
return this;
}
/**
* @param recursive
* defaults to false, but if true, lists all accounts from the parent specified by the
* domain id till leaves.
*/
public ListAccountsOptions recursive(boolean recursive) {
this.queryParameters.replaceValues("isrecursive", ImmutableSet.of(recursive + ""));
return this;
}
public static class Builder {
/**
* @see ListAccountsOptions#accountInDomain
*/
public static ListAccountsOptions accountInDomain(String account, long domain) {
ListAccountsOptions options = new ListAccountsOptions();
return options.accountInDomain(account, domain);
}
/**
* @see ListAccountsOptions#domainId
*/
public static ListAccountsOptions domainId(long id) {
ListAccountsOptions options = new ListAccountsOptions();
return options.domainId(id);
}
/**
* @see ListAccountsOptions#id
*/
public static ListAccountsOptions id(long id) {
ListAccountsOptions options = new ListAccountsOptions();
return options.id(id);
}
/**
* @see ListAccountsOptions#name
*/
public static ListAccountsOptions name(String name) {
ListAccountsOptions options = new ListAccountsOptions();
return options.name(name);
}
/**
* @see ListAccountsOptions#state
*/
public static ListAccountsOptions state(String state) {
ListAccountsOptions options = new ListAccountsOptions();
return options.state(state);
}
/**
* @see ListAccountsOptions#cleanupRequired
*/
public static ListAccountsOptions cleanupRequired(boolean cleanupRequired) {
ListAccountsOptions options = new ListAccountsOptions();
return options.cleanupRequired(cleanupRequired);
}
/**
* @see ListAccountsOptions#recursive
*/
public static ListAccountsOptions recursive(boolean recursive) {
ListAccountsOptions options = new ListAccountsOptions();
return options.recursive(recursive);
}
}
/**
* {@inheritDoc}
*/
@Override
public ListAccountsOptions accountInDomain(String account, long domain) {
return ListAccountsOptions.class.cast(super.accountInDomain(account, domain));
}
/**
* {@inheritDoc}
*/
@Override
public ListAccountsOptions domainId(long domainId) {
return ListAccountsOptions.class.cast(super.domainId(domainId));
}
}

View File

@ -0,0 +1,82 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.User;
import com.google.common.base.Predicate;
/**
*
* @author Adrian Cole
*/
public class UserPredicates {
public static class ApiKeyEquals implements Predicate<User> {
private final String apiKey;
public ApiKeyEquals(String apiKey) {
this.apiKey = checkNotNull(apiKey, "apiKey");
}
@Override
public boolean apply(User input) {
return apiKey.equals(checkNotNull(input, "user").getApiKey());
}
@Override
public String toString() {
return "apiKeyEquals(" + apiKey + ")";
}
}
/**
*
* @return true, if the user's apiKey is the following
*/
public static Predicate<User> apiKeyEquals(String apiKey) {
return new ApiKeyEquals(apiKey);
}
public static enum IsUserAccount implements Predicate<User> {
INSTANCE;
@Override
public boolean apply(User input) {
return checkNotNull(input, "user").getAccountType() == Account.Type.USER;
}
@Override
public String toString() {
return "isUserAccount()";
}
}
/**
*
* @return true, if the user's apiKey is the following
*/
public static Predicate<User> isUserAccount() {
return IsUserAccount.INSTANCE;
}
}

View File

@ -22,13 +22,7 @@ import java.io.IOException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import org.jclouds.cloudstack.features.BaseCloudStackAsyncClientTest; import org.jclouds.cloudstack.features.BaseCloudStackAsyncClientTest;
import org.jclouds.cloudstack.features.FirewallClient;
import org.jclouds.cloudstack.features.GuestOSClient;
import org.jclouds.cloudstack.features.HypervisorClient;
import org.jclouds.cloudstack.features.LoadBalancerClient;
import org.jclouds.cloudstack.features.NATClient;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -61,6 +55,8 @@ public class CloudStackAsyncClientTest extends BaseCloudStackAsyncClientTest<Clo
assert syncClient.getLoadBalancerClient() != null; assert syncClient.getLoadBalancerClient() != null;
assert syncClient.getGuestOSClient() != null; assert syncClient.getGuestOSClient() != null;
assert syncClient.getHypervisorClient() != null; assert syncClient.getHypervisorClient() != null;
assert syncClient.getConfigurationClient() != null;
assert syncClient.getAccountClient() != null;
} }
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
@ -77,6 +73,8 @@ public class CloudStackAsyncClientTest extends BaseCloudStackAsyncClientTest<Clo
assert asyncClient.getLoadBalancerClient() != null; assert asyncClient.getLoadBalancerClient() != null;
assert asyncClient.getGuestOSClient() != null; assert asyncClient.getGuestOSClient() != null;
assert asyncClient.getHypervisorClient() != null; assert asyncClient.getHypervisorClient() != null;
assert asyncClient.getConfigurationClient() != null;
assert asyncClient.getAccountClient() != null;
} }
@Override @Override

View File

@ -65,7 +65,7 @@
// * // *
// * @author Adrian Cole // * @author Adrian Cole
// */ // */
//@Test(groups = "live", sequential = true, testName = "CloudStackClientLiveTest") //@Test(groups = "live", singleThreaded = true, testName = "CloudStackClientLiveTest")
//public class CloudStackClientLiveTest extends ReadOnlyCloudStackClientLiveTest { //public class CloudStackClientLiveTest extends ReadOnlyCloudStackClientLiveTest {
// //
// protected String prefix = System.getProperty("user.name") + ".test"; // protected String prefix = System.getProperty("user.name") + ".test";

View File

@ -0,0 +1,101 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.cloudstack.options.ListAccountsOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code AccountAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "AccountAsyncClientTest")
public class AccountAsyncClientTest extends BaseCloudStackAsyncClientTest<AccountAsyncClient> {
public void testListAccounts() throws SecurityException, NoSuchMethodException, IOException {
Method method = AccountAsyncClient.class.getMethod("listAccounts", ListAccountsOptions[].class);
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listAccounts HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testListAccountsOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AccountAsyncClient.class.getMethod("listAccounts", ListAccountsOptions[].class);
HttpRequest httpRequest = processor.createRequest(method, ListAccountsOptions.Builder.accountInDomain("jclouds",
123));
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listAccounts&account=jclouds&domainid=123 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetAccount() throws SecurityException, NoSuchMethodException, IOException {
Method method = AccountAsyncClient.class.getMethod("getAccount", long.class);
HttpRequest httpRequest = processor.createRequest(method, 3l);
assertRequestLineEquals(httpRequest,
"GET http://localhost:8080/client/api?response=json&command=listAccounts&id=3 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValueInSet.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<AccountAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AccountAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,84 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.features;
import static org.testng.Assert.assertEquals;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.User;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code AccountClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "AccountClientLiveTest")
public class AccountClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListAccount() throws Exception {
for (Account securityAccount : client.getAccountClient().listAccounts())
checkAccount(securityAccount);
}
protected void checkAccount(Account account) {
assert account.getId() > 0 : account;
assertEquals(account.toString(), client.getAccountClient().getAccount(account.getId()).toString());
assert account.getName() != null : account;
assert account.getType() != null && account.getType() != Account.Type.UNRECOGNIZED : account;
assert account.getDomain() != null : account;
assert account.getDomainId() >= 0 : account;
assert account.getUsers() != null : account;
for (User user : account.getUsers()) {
assert user.getName() != null : user;
assert user.getAccountType().equals(account.getType()) : user;
assert user.getDomain().equals(account.getDomain()) : user;
assert user.getDomainId() == account.getDomainId() : user;
assert user.getApiKey() != null : user;
assert user.getCreated() != null : user;
assert user.getEmail() != null : user;
assert user.getLastName() != null : user;
assert user.getFirstName() != null : user;
assert user.getId() > 0 : user;
assert user.getSecretKey() != null : user;
assert user.getState() != null : user;
}
assert account.getIPsAvailable() == null || account.getIPsAvailable() >= 0 : account;
assert account.getIPLimit() == null || account.getIPLimit() >= 0 : account;
assert account.getIPs() >= 0 : account;
assert account.getReceivedBytes() >= 0 : account;
assert account.getSentBytes() >= 0 : account;
assert account.getSnapshotsAvailable() == null || account.getSnapshotsAvailable() >= 0 : account;
assert account.getSnapshotLimit() == null || account.getSnapshotLimit() >= 0 : account;
assert account.getSnapshots() >= 0 : account;
assert account.getState() != null && account.getState() != Account.State.UNRECOGNIZED : account;
assert account.getTemplatesAvailable() == null || account.getTemplatesAvailable() >= 0 : account;
assert account.getTemplateLimit() == null || account.getTemplateLimit() >= 0 : account;
assert account.getTemplates() >= 0 : account;
assert account.getVMsAvailable() == null || account.getVMsAvailable() >= 0 : account;
assert account.getVMLimit() == null || account.getVMLimit() >= 0 : account;
assert account.getVMsRunning() >= 0 : account;
assert account.getVMsStopped() >= 0 : account;
assert account.getVMs() >= 0 : account;
assert account.getVolumesAvailable() == null || account.getVolumesAvailable() >= 0 : account;
assert account.getVolumeLimit() == null || account.getVolumeLimit() >= 0 : account;
assert account.getVolumes() >= 0 : account;
}
}

View File

@ -30,17 +30,16 @@ import org.jclouds.cloudstack.domain.PublicIPAddress;
import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions; import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
/** /**
* Tests behavior of {@code PublicIPAddressClientLiveTest} * Tests behavior of {@code AddressClient}
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "PublicIPAddressClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "AddressClientLiveTest")
public class AddressClientLiveTest extends BaseCloudStackClientLiveTest { public class AddressClientLiveTest extends BaseCloudStackClientLiveTest {
private boolean networksEnabled; private boolean networksEnabled;

View File

@ -31,7 +31,7 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "AsyncJobClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "AsyncJobClientLiveTest")
public class AsyncJobClientLiveTest extends BaseCloudStackClientLiveTest { public class AsyncJobClientLiveTest extends BaseCloudStackClientLiveTest {
// disabled as it takes too long // disabled as it takes too long
@Test(enabled = false) @Test(enabled = false)

View File

@ -27,9 +27,12 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.cloudstack.CloudStackAsyncClient; import org.jclouds.cloudstack.CloudStackAsyncClient;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.Account;
import org.jclouds.cloudstack.domain.User;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.functions.ReuseOrAssociateNewPublicIPAddress; import org.jclouds.cloudstack.functions.ReuseOrAssociateNewPublicIPAddress;
import org.jclouds.cloudstack.predicates.JobComplete; import org.jclouds.cloudstack.predicates.JobComplete;
import org.jclouds.cloudstack.predicates.UserPredicates;
import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed; import org.jclouds.cloudstack.predicates.VirtualMachineDestroyed;
import org.jclouds.cloudstack.predicates.VirtualMachineRunning; import org.jclouds.cloudstack.predicates.VirtualMachineRunning;
import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.ExecResponse;
@ -47,6 +50,7 @@ import org.testng.annotations.BeforeGroups;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
@ -120,6 +124,15 @@ public class BaseCloudStackClientLiveTest {
overrides); overrides);
client = context.getApi(); client = context.getApi();
// check access
Iterable<User> users = Iterables.concat(client.getAccountClient().listAccounts());
User currentUser = Iterables.find(users, UserPredicates.apiKeyEquals(identity));
if (currentUser.getAccountType() != Account.Type.USER)
throw new IllegalArgumentException(String.format(
"invalid account type: %s, please specify an apiKey of a USER, for example: %s", currentUser
.getAccountType(), Iterables.filter(users, UserPredicates.isUserAccount())));
injector = Guice.createInjector(new JschSshClientModule(), new Log4JLoggingModule()); injector = Guice.createInjector(new JschSshClientModule(), new Log4JLoggingModule());
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, 1, TimeUnit.SECONDS);

View File

@ -26,7 +26,7 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "ConfigurationClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "ConfigurationClientLiveTest")
public class ConfigurationClientLiveTest extends BaseCloudStackClientLiveTest { public class ConfigurationClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListCapabilities() throws Exception { public void testListCapabilities() throws Exception {

View File

@ -43,7 +43,7 @@ import com.google.common.base.Predicate;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "FirewallClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "FirewallClientLiveTest")
public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest { public class FirewallClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null; private PublicIPAddress ip = null;
private VirtualMachine vm; private VirtualMachine vm;

View File

@ -35,7 +35,7 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "GuestOSClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "GuestOSClientLiveTest")
public class GuestOSClientLiveTest extends BaseCloudStackClientLiveTest { public class GuestOSClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListOSTypes() throws Exception { public void testListOSTypes() throws Exception {

View File

@ -30,7 +30,7 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "HypervisorClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "HypervisorClientLiveTest")
public class HypervisorClientLiveTest extends BaseCloudStackClientLiveTest { public class HypervisorClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListHypervisors() throws Exception { public void testListHypervisors() throws Exception {

View File

@ -49,7 +49,7 @@ import com.google.common.base.Predicate;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "LoadBalancerClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "LoadBalancerClientLiveTest")
public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest { public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null; private PublicIPAddress ip = null;
private VirtualMachine vm; private VirtualMachine vm;

View File

@ -46,7 +46,7 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "NATClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "NATClientLiveTest")
public class NATClientLiveTest extends BaseCloudStackClientLiveTest { public class NATClientLiveTest extends BaseCloudStackClientLiveTest {
private PublicIPAddress ip = null; private PublicIPAddress ip = null;
private VirtualMachine vm; private VirtualMachine vm;

View File

@ -35,7 +35,7 @@ import com.google.common.collect.Iterables;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "NetworkClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "NetworkClientLiveTest")
public class NetworkClientLiveTest extends BaseCloudStackClientLiveTest { public class NetworkClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListNetworks() throws Exception { public void testListNetworks() throws Exception {

View File

@ -40,7 +40,7 @@ import com.google.common.collect.Iterables;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "OfferingClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "OfferingClientLiveTest")
public class OfferingClientLiveTest extends BaseCloudStackClientLiveTest { public class OfferingClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListDiskOfferings() throws Exception { public void testListDiskOfferings() throws Exception {

View File

@ -45,7 +45,7 @@ import com.google.common.collect.Iterables;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "SecurityGroupClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "SecurityGroupClientLiveTest")
public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest { public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
public SecurityGroupClientLiveTest() { public SecurityGroupClientLiveTest() {
prefix += "2"; prefix += "2";
@ -63,7 +63,7 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest {
@Override @Override
public boolean apply(Zone arg0) { public boolean apply(Zone arg0) {
return arg0.isSecurityGroupsEnabled(); return true;// return arg0.isSecurityGroupsEnabled();
} }
}); });

View File

@ -34,7 +34,7 @@ import com.google.common.collect.Iterables;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "TemplateClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "TemplateClientLiveTest")
public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest { public class TemplateClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListTemplates() throws Exception { public void testListTemplates() throws Exception {

View File

@ -34,7 +34,6 @@ import java.util.concurrent.ExecutionException;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.NIC; import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.ServiceOffering;
@ -67,7 +66,7 @@ import com.google.common.net.HostSpecifier;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "VirtualMachineClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "VirtualMachineClientLiveTest")
public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
private VirtualMachine vm = null; private VirtualMachine vm = null;
@ -132,7 +131,6 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
throw new NoSuchElementException(templatePredicate.toString()); throw new NoSuchElementException(templatePredicate.toString());
} }
long templateId = get(templates, 0).getId(); long templateId = get(templates, 0).getId();
long serviceOfferingId = DEFAULT_SIZE_ORDERING.min(client.getOfferingClient().listServiceOfferings()).getId(); long serviceOfferingId = DEFAULT_SIZE_ORDERING.min(client.getOfferingClient().listServiceOfferings()).getId();
System.out.printf("serviceOfferingId %d, templateId %d, zoneId %d, options %s%n", serviceOfferingId, templateId, System.out.printf("serviceOfferingId %d, templateId %d, zoneId %d, options %s%n", serviceOfferingId, templateId,
@ -187,12 +185,14 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId()); vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId());
assertEquals(vm.getState(), VirtualMachine.State.STOPPED); assertEquals(vm.getState(), VirtualMachine.State.STOPPED);
if (vm.isPasswordEnabled()) {
job = client.getVirtualMachineClient().resetPasswordForVirtualMachine(vm.getId()); job = client.getVirtualMachineClient().resetPasswordForVirtualMachine(vm.getId());
assert jobComplete.apply(job); assert jobComplete.apply(job);
vm = client.getAsyncJobClient().<VirtualMachine> getAsyncJob(job).getResult(); vm = client.getAsyncJobClient().<VirtualMachine> getAsyncJob(job).getResult();
if (vm.getPassword() != null) { if (vm.getPassword() != null) {
conditionallyCheckSSH(); conditionallyCheckSSH();
} }
}
job = client.getVirtualMachineClient().startVirtualMachine(vm.getId()); job = client.getVirtualMachineClient().startVirtualMachine(vm.getId());
assert jobComplete.apply(job); assert jobComplete.apply(job);
@ -263,17 +263,15 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
assert nic.getGateway() != null : vm; assert nic.getGateway() != null : vm;
assert nic.getIPAddress() != null : vm; assert nic.getIPAddress() != null : vm;
break; break;
default: case STARTING:
if (nic.getGuestIPType() == GuestIPType.VIRTUAL) {
assert nic.getNetmask() != null : vm;
assert nic.getGateway() != null : vm;
assert nic.getIPAddress() != null : vm;
} else {
assert nic.getNetmask() == null : vm; assert nic.getNetmask() == null : vm;
assert nic.getGateway() == null : vm; assert nic.getGateway() == null : vm;
assert nic.getIPAddress() == null : vm; assert nic.getIPAddress() == null : vm;
}
break; break;
default:
assert nic.getNetmask() != null : vm;
assert nic.getGateway() != null : vm;
assert nic.getIPAddress() != null : vm;
} }
} }

View File

@ -35,7 +35,7 @@ import com.google.common.collect.Iterables;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "ZoneClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "ZoneClientLiveTest")
public class ZoneClientLiveTest extends BaseCloudStackClientLiveTest { public class ZoneClientLiveTest extends BaseCloudStackClientLiveTest {
public void testListZones() throws Exception { public void testListZones() throws Exception {

View File

@ -0,0 +1,112 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.cloudstack.options;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.accountInDomain;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.cleanupRequired;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.domainId;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.id;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.recursive;
import static org.jclouds.cloudstack.options.ListAccountsOptions.Builder.state;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
/**
* Tests behavior of {@code ListAccountsOptions}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class ListAccountsOptionsTest {
public void testAccountInDomainId() {
ListAccountsOptions options = new ListAccountsOptions().accountInDomain("adrian", 6);
assertEquals(ImmutableList.of("adrian"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testAccountInDomainIdStatic() {
ListAccountsOptions options = accountInDomain("adrian", 6);
assertEquals(ImmutableList.of("adrian"), options.buildQueryParameters().get("account"));
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testName() {
ListAccountsOptions options = new ListAccountsOptions().id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testNameStatic() {
ListAccountsOptions options = id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testRecursive() {
ListAccountsOptions options = new ListAccountsOptions().recursive(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("isrecursive"));
}
public void testRecursiveStatic() {
ListAccountsOptions options = recursive(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("isrecursive"));
}
public void testState() {
ListAccountsOptions options = new ListAccountsOptions().state("state");
assertEquals(ImmutableList.of("state"), options.buildQueryParameters().get("state"));
}
public void testStateStatic() {
ListAccountsOptions options = state("state");
assertEquals(ImmutableList.of("state"), options.buildQueryParameters().get("state"));
}
public void testCleanupRequired() {
ListAccountsOptions options = new ListAccountsOptions().cleanupRequired(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("iscleanuprequired"));
}
public void testCleanupRequiredStatic() {
ListAccountsOptions options = cleanupRequired(true);
assertEquals(ImmutableList.of("true"), options.buildQueryParameters().get("iscleanuprequired"));
}
public void testId() {
ListAccountsOptions options = new ListAccountsOptions().id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testDomainId() {
ListAccountsOptions options = new ListAccountsOptions().domainId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("domainid"));
}
public void testIdStatic() {
ListAccountsOptions options = id(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("id"));
}
public void testDomainIdStatic() {
ListAccountsOptions options = domainId(6);
assertEquals(ImmutableList.of("6"), options.buildQueryParameters().get("domainid"));
}
}