diff --git a/sandbox/deltacloud/pom.xml b/sandbox/deltacloud/pom.xml
index d66b991628..140ca063d6 100644
--- a/sandbox/deltacloud/pom.xml
+++ b/sandbox/deltacloud/pom.xml
@@ -71,6 +71,12 @@
test-jar
test
+
+ ${project.groupId}
+ jclouds-jsch
+ ${project.version}
+ test
+
log4j
log4j
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java
index 86dac7b9e8..5392910222 100644
--- a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -34,9 +35,12 @@ import org.jclouds.deltacloud.collections.DeltacloudCollection;
import org.jclouds.deltacloud.collections.Images;
import org.jclouds.deltacloud.collections.Instances;
import org.jclouds.deltacloud.domain.Image;
+import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.deltacloud.xml.ImageHandler;
import org.jclouds.deltacloud.xml.ImagesHandler;
+import org.jclouds.deltacloud.xml.InstanceHandler;
+import org.jclouds.deltacloud.xml.InstancesHandler;
import org.jclouds.deltacloud.xml.LinksHandler;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.Endpoint;
@@ -46,6 +50,7 @@ import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
@@ -88,12 +93,47 @@ public interface DeltacloudAsyncClient {
@XMLResponseParser(ImageHandler.class)
ListenableFuture getImage(@EndpointParam URI imageHref);
+ /**
+ * @see DeltacloudClient#listInstances
+ */
+ @GET
+ @Endpoint(Instances.class)
+ @Path("")
+ @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
+ @XMLResponseParser(InstancesHandler.class)
+ ListenableFuture extends Set> listInstances();
+
+ /**
+ * @see DeltacloudClient#getInstance
+ */
+ @GET
+ @ExceptionParser(ReturnNullOnNotFoundOr404.class)
+ @Path("")
+ @XMLResponseParser(InstanceHandler.class)
+ ListenableFuture getInstance(@EndpointParam URI instanceHref);
+
/**
* @see DeltacloudClient#createInstance
*/
@POST
@Endpoint(Instances.class)
@Path("")
- ListenableFuture createInstance(@FormParam("image_id") String imageId, CreateInstanceOptions... options);
+ @XMLResponseParser(InstanceHandler.class)
+ ListenableFuture createInstance(@FormParam("image_id") String imageId, CreateInstanceOptions... options);
+
+ /**
+ * @see DeltacloudClient#performInstanceAction
+ */
+ @POST
+ @Path("")
+ ListenableFuture performAction(@EndpointParam URI actionRef);
+
+ /**
+ * @see DeltacloudClient#deleteResource
+ */
+ @DELETE
+ @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
+ @Path("")
+ ListenableFuture deleteResource(@EndpointParam URI resourceHref);
}
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java
index a993777a56..9b13dff82b 100644
--- a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java
@@ -27,7 +27,9 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.deltacloud.collections.DeltacloudCollection;
import org.jclouds.deltacloud.domain.Image;
+import org.jclouds.deltacloud.domain.Instance;
import org.jclouds.deltacloud.options.CreateInstanceOptions;
+import org.jclouds.rest.annotations.EndpointParam;
/**
* Provides synchronous access to deltacloud.
@@ -61,6 +63,20 @@ public interface DeltacloudClient {
*/
Image getImage(URI imageHref);
+ /**
+ * The instances collection will return a set of all instances available to the current user.
+ *
+ * @return instances viewable to the user or empty set
+ */
+ Set extends Instance> listInstances();
+
+ /**
+ *
+ * @param instanceHref
+ * @return instance or null, if not found
+ */
+ Instance getInstance(URI instanceHref);
+
/**
* Create a new Instance
*
@@ -76,5 +92,21 @@ public interface DeltacloudClient {
* includes realm, hardware profile, etc.
* @return newly-created instance including a URL to retrieve the instance in the future.
*/
- String createInstance(String imageId, CreateInstanceOptions... options);
+ Instance createInstance(String imageId, CreateInstanceOptions... options);
+
+ /**
+ * perform a specific action.
+ *
+ * @param actionRef
+ * reference from {@link Instance#getActions()}
+ */
+ void performAction(@EndpointParam URI actionRef);
+
+ /**
+ * delete a resource, such as {@link Instance}
+ *
+ * @param resourceHref
+ * reference from {@link Instance#getHref()}
+ */
+ void deleteResource(@EndpointParam URI resourceHref);
}
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/Instance.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/Instance.java
new file mode 100644
index 0000000000..becca4aa70
--- /dev/null
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/Instance.java
@@ -0,0 +1,241 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * An instance is a concrete machine realized from an image.
+ *
+ * @author Adrian Cole
+ */
+public class Instance {
+ private final URI href;
+ private final String id;
+ private final String ownerId;
+ @Nullable
+ private final String name;
+ private final URI image;
+ private final URI hardwareProfile;
+ private final URI realm;
+ private final InstanceState state;
+ private final Map actions;
+ private final Set publicAddresses;
+ private final Set privateAddresses;
+
+ public Instance(URI href, String id, String ownerId, @Nullable String name, URI image, URI hardwareProfile,
+ URI realm, InstanceState state, Map actions, Set publicAddresses,
+ Set privateAddresses) {
+ this.href = checkNotNull(href, "href");
+ this.id = checkNotNull(id, "id");
+ this.ownerId = checkNotNull(ownerId, "ownerId");
+ this.name = name;
+ this.image = checkNotNull(image, "image");
+ this.hardwareProfile = checkNotNull(hardwareProfile, "hardwareProfile");
+ this.realm = checkNotNull(realm, "realm");
+ this.state = checkNotNull(state, "state");
+ this.actions = ImmutableMap.copyOf(checkNotNull(actions, "actions"));
+ this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses"));
+ this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses"));
+ }
+
+ /**
+ *
+ * @return URL to manipulate a specific instance
+ */
+ public URI getHref() {
+ return href;
+ }
+
+ /**
+ *
+ * @return A unique identifier for the instance
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ *
+ * @return An opaque identifier which indicates the owner of an instance
+ */
+ public String getOwnerId() {
+ return ownerId;
+ }
+
+ /**
+ *
+ * @return An optional short label describing the instance
+ */
+ @Nullable
+ public String getName() {
+ return name;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public URI getImage() {
+ return image;
+ }
+
+ /**
+ *
+ * @return a link to the hardware profile in use by the instance
+ */
+ public URI getHardwareProfile() {
+ return hardwareProfile;
+ }
+
+ /**
+ *
+ * @return a link to the realm where the instance is deployed
+ */
+ public URI getRealm() {
+ return realm;
+ }
+
+ /**
+ *
+ * @return indicator of the instance's current state
+ */
+ public InstanceState getState() {
+ return state;
+ }
+
+ /**
+ *
+ * @return valid actions for the instance, along with the URL which may be used to perform the
+ * action
+ */
+ public Map getActions() {
+ return actions;
+ }
+
+ /**
+ *
+ * @return publicly routable IP addresses or names for the instance
+ */
+ public Set getPublicAddresses() {
+ return publicAddresses;
+ }
+
+ /**
+ *
+ * @return Private network IP addresses or names for the instance
+ */
+ public Set getPrivateAddresses() {
+ return privateAddresses;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((actions == null) ? 0 : actions.hashCode());
+ result = prime * result + ((hardwareProfile == null) ? 0 : hardwareProfile.hashCode());
+ result = prime * result + ((href == null) ? 0 : href.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((image == null) ? 0 : image.hashCode());
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
+ result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
+ result = prime * result + ((realm == null) ? 0 : realm.hashCode());
+ result = prime * result + ((state == null) ? 0 : state.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;
+ Instance other = (Instance) obj;
+ if (actions == null) {
+ if (other.actions != null)
+ return false;
+ } else if (!actions.equals(other.actions))
+ return false;
+ if (hardwareProfile == null) {
+ if (other.hardwareProfile != null)
+ return false;
+ } else if (!hardwareProfile.equals(other.hardwareProfile))
+ return false;
+ if (href == null) {
+ if (other.href != null)
+ return false;
+ } else if (!href.equals(other.href))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (image == null) {
+ if (other.image != null)
+ return false;
+ } else if (!image.equals(other.image))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (privateAddresses == null) {
+ if (other.privateAddresses != null)
+ return false;
+ } else if (!privateAddresses.equals(other.privateAddresses))
+ return false;
+ if (publicAddresses == null) {
+ if (other.publicAddresses != null)
+ return false;
+ } else if (!publicAddresses.equals(other.publicAddresses))
+ return false;
+ if (realm == null) {
+ if (other.realm != null)
+ return false;
+ } else if (!realm.equals(other.realm))
+ return false;
+ if (state != other.state)
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "[href=" + href + ", id=" + id + ", name=" + name + ", image=" + image + ", hardwareProfile="
+ + hardwareProfile + ", realm=" + realm + ", state=" + state + ", actions=" + actions + ", publicAddresses="
+ + publicAddresses + ", privateAddresses=" + privateAddresses + "]";
+ }
+
+}
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceAction.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceAction.java
new file mode 100644
index 0000000000..7f43b00ada
--- /dev/null
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceAction.java
@@ -0,0 +1,57 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ *
+ * Indicator of the instance's current action
+ *
+ * @author Adrian Cole
+ *
+ */
+public enum InstanceAction {
+
+ REBOOT,
+
+ START,
+
+ STOP,
+
+ UNRECOGNIZED;
+
+ public String value() {
+ return name().toLowerCase();
+ }
+
+ @Override
+ public String toString() {
+ return value();
+ }
+
+ public static InstanceAction fromValue(String action) {
+ try {
+ return valueOf(checkNotNull(action, "action").toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return UNRECOGNIZED;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceState.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceState.java
new file mode 100644
index 0000000000..aeded33830
--- /dev/null
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/domain/InstanceState.java
@@ -0,0 +1,59 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ *
+ * Indicator of the instance's current state
+ *
+ * @author Adrian Cole
+ *
+ */
+public enum InstanceState {
+
+ /**
+ * the instance is in the process of being launched
+ */
+ PENDING,
+
+ /**
+ * the instance is stopped
+ */
+ STOPPED,
+ /**
+ * the instance launched (although the boot process might not be completed)
+ */
+ RUNNING,
+
+ /**
+ * state returned as something besides the above.
+ */
+ UNRECOGNIZED;
+
+ public static InstanceState fromValue(String state) {
+ try {
+ return valueOf(checkNotNull(state, "state"));
+ } catch (IllegalArgumentException e) {
+ return UNRECOGNIZED;
+ }
+ }
+}
\ No newline at end of file
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstanceHandler.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstanceHandler.java
new file mode 100644
index 0000000000..cf2d6ae2ea
--- /dev/null
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstanceHandler.java
@@ -0,0 +1,135 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.xml;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.deltacloud.domain.Instance;
+import org.jclouds.deltacloud.domain.InstanceAction;
+import org.jclouds.deltacloud.domain.InstanceState;
+import org.jclouds.http.functions.ParseSax;
+import org.jclouds.util.Utils;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * @author Adrian Cole
+ */
+public class InstanceHandler extends ParseSax.HandlerWithResult {
+ private StringBuilder currentText = new StringBuilder();
+
+ private URI href;
+ private String id;
+ private String ownerId;
+ private String name;
+ private URI image;
+ private URI hardwareProfile;
+ private URI realm;
+ private InstanceState state;
+ private Map actions = Maps.newLinkedHashMap();
+ private Set publicAddresses = Sets.newLinkedHashSet();
+ private Set privateAddresses = Sets.newLinkedHashSet();
+
+ private boolean inPublicAddresses;
+ private boolean inPrivateAddresses;
+
+ private Instance instance;
+
+ public Instance getResult() {
+ return instance;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
+ Map attributes = Utils.cleanseAttributes(attrs);
+ if (qName.equals("public_addresses")) {
+ inPublicAddresses = true;
+ } else if (qName.equals("private_addresses")) {
+ inPrivateAddresses = true;
+ } else if (qName.equals("instance")) {
+ String href = attributes.get("href");
+ if (href != null) {
+ this.href = URI.create(href);
+ }
+ this.id = attributes.get("id");
+ } else if (qName.equals("link")) {
+ String rel = attributes.get("rel");
+ if (rel != null) {
+ InstanceAction action = InstanceAction.fromValue(rel);
+ if (action != InstanceAction.UNRECOGNIZED) {
+ actions.put(action, URI.create(attributes.get("href")));
+ }
+ }
+ } else if (attributes.containsKey("href")) {
+ URI href = URI.create(attributes.get("href"));
+ if (qName.equals("image"))
+ this.image = href;
+ else if (qName.equals("hardware_profile"))
+ this.hardwareProfile = href;
+ else if (qName.equals("realm"))
+ this.realm = href;
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (qName.endsWith("public_addresses")) {
+ inPublicAddresses = false;
+ } else if (qName.endsWith("private_addresses")) {
+ inPrivateAddresses = false;
+ }
+ if (qName.equalsIgnoreCase("owner_id")) {
+ this.ownerId = currentText.toString().trim();
+ } else if (qName.equalsIgnoreCase("name")) {
+ this.name = currentText.toString().trim();
+ } else if (qName.equalsIgnoreCase("state")) {
+ this.state = InstanceState.fromValue(currentText.toString().trim());
+ } else if (qName.equalsIgnoreCase("address")) {
+ if (inPublicAddresses)
+ this.publicAddresses.add(currentText.toString().trim());
+ else if (inPrivateAddresses)
+ this.privateAddresses.add(currentText.toString().trim());
+ } else if (qName.equalsIgnoreCase("instance")) {
+ this.instance = new Instance(href, id, ownerId, name, image, hardwareProfile, realm, state, actions,
+ publicAddresses, privateAddresses);
+ this.href = null;
+ this.id = null;
+ this.ownerId = null;
+ this.name = null;
+ this.image = null;
+ this.hardwareProfile = null;
+ this.realm = null;
+ this.state = null;
+ this.actions = Maps.newLinkedHashMap();
+ this.publicAddresses = Sets.newLinkedHashSet();
+ this.privateAddresses = Sets.newLinkedHashSet();
+ }
+ currentText = new StringBuilder();
+ }
+
+ public void characters(char ch[], int start, int length) {
+ currentText.append(ch, start, length);
+ }
+}
diff --git a/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstancesHandler.java b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstancesHandler.java
new file mode 100644
index 0000000000..cc83b0bfc1
--- /dev/null
+++ b/sandbox/deltacloud/src/main/java/org/jclouds/deltacloud/xml/InstancesHandler.java
@@ -0,0 +1,69 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.xml;
+
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.deltacloud.domain.Instance;
+import org.jclouds.http.functions.ParseSax;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import com.google.common.collect.Sets;
+
+/**
+ * @author Adrian Cole
+ */
+public class InstancesHandler extends ParseSax.HandlerWithResult> {
+ private StringBuilder currentText = new StringBuilder();
+
+ private Set instances = Sets.newLinkedHashSet();
+ private final InstanceHandler instanceHandler;
+
+ @Inject
+ public InstancesHandler(InstanceHandler locationHandler) {
+ this.instanceHandler = locationHandler;
+ }
+
+ public Set extends Instance> getResult() {
+ return instances;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ instanceHandler.startElement(uri, localName, qName, attributes);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ instanceHandler.endElement(uri, localName, qName);
+ if (qName.equals("instance") && currentText.toString().trim().equals("")) {
+ this.instances.add(instanceHandler.getResult());
+ }
+ currentText = new StringBuilder();
+ }
+
+ public void characters(char ch[], int start, int length) {
+ instanceHandler.characters(ch, start, length);
+ currentText.append(ch, start, length);
+ }
+}
diff --git a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudAsyncClientTest.java b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudAsyncClientTest.java
index 4455b7497b..95e5e775c4 100644
--- a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudAsyncClientTest.java
+++ b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudAsyncClientTest.java
@@ -32,18 +32,22 @@ import org.jclouds.deltacloud.config.DeltacloudRestClientModule;
import org.jclouds.deltacloud.options.CreateInstanceOptions;
import org.jclouds.deltacloud.xml.ImageHandler;
import org.jclouds.deltacloud.xml.ImagesHandler;
+import org.jclouds.deltacloud.xml.InstanceHandler;
+import org.jclouds.deltacloud.xml.InstancesHandler;
import org.jclouds.deltacloud.xml.LinksHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ReturnStringIf2xx;
+import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
+import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
+import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
@@ -117,6 +121,36 @@ public class DeltacloudAsyncClientTest extends RestClientTest socketTester;
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");
+ identity = System.getProperty("test." + provider + ".identity", "mockuser");
+ credential = System.getProperty("test." + provider + ".credential", "mockpassword");
+ endpoint = System.getProperty("test." + provider + ".endpoint", "http://localhost:3001/api");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
@@ -88,12 +106,7 @@ public class DeltacloudClientLiveTest {
overrides);
client = context.getApi();
- }
-
- @AfterGroups(groups = "live")
- void tearDown() {
- if (context != null)
- context.close();
+ socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS);
}
@Test
@@ -115,14 +128,109 @@ public class DeltacloudClientLiveTest {
}
}
- @Test
- public void testCreateInstance() throws Exception {
- // TODO
+ public void testListAndGetInstances() throws Exception {
+ Set extends Instance> response = client.listInstances();
+ assert null != response;
+ long instanceCount = response.size();
+ assertTrue(instanceCount >= 0);
+ for (Instance instance : response) {
+ Instance newDetails = client.getInstance(instance.getHref());
+ assertEquals(instance, newDetails);
+ }
}
- @Test
- public void testCreateInstanceWithOptions() throws Exception {
+ protected String prefix = System.getProperty("user.name") + ".test";
+ protected Instance instance;
+
+ public void testCreateInstance() throws Exception {
+ Logger.getAnonymousLogger().info("starting instance");
+ instance = client.createInstance(Iterables.get(client.listImages(), 0).getId(),
+ CreateInstanceOptions.Builder.named(prefix));
+ instance = client.getInstance(instance.getHref());
+ checkStartedInstance();
+
+ Instance newInfo = client.getInstance(instance.getHref());
+ checkInstanceMatchesGet(newInfo);
+
+ }
+
+ protected void checkInstanceMatchesGet(Instance newInfo) {
+ assertEquals(newInfo.getHref(), instance.getHref());
+ }
+
+ protected void checkStartedInstance() {
+ System.out.println(new Gson().toJson(instance));
+ assertEquals(instance.getName(), prefix);
+ assertEquals(instance.getState(), InstanceState.RUNNING);
+ }
+
+ @Test(dependsOnMethods = "testCreateInstance")
+ public void testConnectivity() throws Exception {
+ Logger.getAnonymousLogger().info("awaiting ssh");
// TODO
+ // assert socketTester.apply(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0),
+ // 22)) : instance;
+ // doConnectViaSsh(instance, getSshCredentials(instance));
+ }
+
+ private Credentials getSshCredentials(Instance instance2) {
+ // TODO
+ return null;
+ }
+
+ public URI refreshInstanceAndGetAction(InstanceAction action) {
+ return client.getInstance(instance.getHref()).getActions().get(action);
+ }
+
+ @Test(dependsOnMethods = "testConnectivity")
+ public void testLifeCycle() throws Exception {
+ client.performAction(refreshInstanceAndGetAction(InstanceAction.STOP));
+ assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.STOPPED);
+
+ client.performAction(refreshInstanceAndGetAction(InstanceAction.START));
+ assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.RUNNING);
+
+ client.performAction(refreshInstanceAndGetAction(InstanceAction.REBOOT));
+ assertEquals(client.getInstance(instance.getHref()).getState(), InstanceState.RUNNING);
+
+ }
+
+ @Test(dependsOnMethods = "testLifeCycle")
+ public void testDestroyInstance() throws Exception {
+ try {
+ client.deleteResource(instance.getHref());
+ } catch (IllegalArgumentException e) {
+ client.performAction(refreshInstanceAndGetAction(InstanceAction.STOP));
+ client.deleteResource(instance.getHref());
+ assertEquals(client.getInstance(instance.getHref()), null);
+ }
+ }
+
+ protected void doConnectViaSsh(Instance instance, Credentials creds) throws IOException {
+ SshClient ssh = Guice.createInjector(new JschSshClientModule()).getInstance(SshClient.Factory.class)
+ .create(new IPSocket(Iterables.get(instance.getPublicAddresses(), 0), 22), creds);
+ try {
+ ssh.connect();
+ ExecResponse hello = ssh.exec("echo hello");
+ assertEquals(hello.getOutput().trim(), "hello");
+ System.err.println(ssh.exec("df -k").getOutput());
+ System.err.println(ssh.exec("mount").getOutput());
+ System.err.println(ssh.exec("uname -a").getOutput());
+ } finally {
+ if (ssh != null)
+ ssh.disconnect();
+ }
+ }
+
+ @AfterGroups(groups = "live")
+ protected void tearDown() {
+ try {
+ client.deleteResource(instance.getHref());
+ } catch (Exception e) {
+ // no need to check null or anything as we swallow all
+ }
+ if (context != null)
+ context.close();
}
}
diff --git a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstanceHandlerTest.java b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstanceHandlerTest.java
new file mode 100644
index 0000000000..f07847e87d
--- /dev/null
+++ b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstanceHandlerTest.java
@@ -0,0 +1,74 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.xml;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.net.URI;
+
+import org.jclouds.deltacloud.domain.Instance;
+import org.jclouds.deltacloud.domain.InstanceAction;
+import org.jclouds.deltacloud.domain.InstanceState;
+import org.jclouds.http.functions.ParseSax;
+import org.jclouds.http.functions.config.SaxParserModule;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * Tests behavior of {@code InstanceHandler}
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit")
+public class InstanceHandlerTest {
+
+ static ParseSax createParser() {
+ Injector injector = Guice.createInjector(new SaxParserModule());
+ ParseSax parser = injector.getInstance(ParseSax.Factory.class).create(
+ injector.getInstance(InstanceHandler.class));
+ return parser;
+ }
+
+ public static Instance parseInstance() {
+ return parseInstance("/test_get_instance.xml");
+ }
+
+ public static Instance parseInstance(String resource) {
+ InputStream is = InstanceHandlerTest.class.getResourceAsStream(resource);
+ return createParser().parse(is);
+ }
+
+ public void test() {
+ Instance expects = new Instance(URI.create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", "larry",
+ "Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"),
+ URI.create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"),
+ URI.create("http://fancycloudprovider.com/api/realms/us"), InstanceState.RUNNING, ImmutableMap.of(
+ InstanceAction.REBOOT, URI.create("http://fancycloudprovider.com/api/instances/inst1/reboot"),
+ InstanceAction.STOP, URI.create("http://fancycloudprovider.com/api/instances/inst1/stop")),
+ ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet.of("inst1.larry.internal"));
+ assertEquals(parseInstance(), expects);
+ }
+
+}
diff --git a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstancesHandlerTest.java b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstancesHandlerTest.java
new file mode 100644
index 0000000000..08a9497494
--- /dev/null
+++ b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/InstancesHandlerTest.java
@@ -0,0 +1,63 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * 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.deltacloud.xml;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Set;
+
+import org.jclouds.deltacloud.domain.Instance;
+import org.jclouds.deltacloud.domain.InstanceAction;
+import org.jclouds.deltacloud.domain.InstanceState;
+import org.jclouds.http.functions.BaseHandlerTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Tests behavior of {@code InstancesHandler}
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit")
+public class InstancesHandlerTest extends BaseHandlerTest {
+
+ @Test
+ public void test() {
+ InputStream is = getClass().getResourceAsStream("/test_list_instances.xml");
+ Set extends Instance> expects = ImmutableSet.of(new Instance(URI
+ .create("http://fancycloudprovider.com/api/instances/inst1"), "inst1", "larry",
+ "Production JBoss Instance", URI.create("http://fancycloudprovider.com/api/images/img3"), URI
+ .create("http://fancycloudprovider.com/api/hardware_profiles/m1-small"), URI
+ .create("http://fancycloudprovider.com/api/realms/us"), InstanceState.RUNNING, ImmutableMap.of(
+ InstanceAction.REBOOT, URI.create("http://fancycloudprovider.com/api/instances/inst1/reboot"),
+ InstanceAction.STOP, URI.create("http://fancycloudprovider.com/api/instances/inst1/stop")),
+ ImmutableSet.of("inst1.larry.fancycloudprovider.com"), ImmutableSet.of("inst1.larry.internal")));
+ System.out.println(factory);
+ System.out.println(injector);
+
+ // not sure why this isn't always automatically called from surefire.
+ setUpInjector();
+ assertEquals(factory.create(injector.getInstance(InstancesHandler.class)).parse(is), expects);
+ }
+}
diff --git a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/handlers/LinksHandlerTest.java b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/LinksHandlerTest.java
similarity index 86%
rename from sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/handlers/LinksHandlerTest.java
rename to sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/LinksHandlerTest.java
index ebe6705ecc..4f8d6da1f6 100644
--- a/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/handlers/LinksHandlerTest.java
+++ b/sandbox/deltacloud/src/test/java/org/jclouds/deltacloud/xml/LinksHandlerTest.java
@@ -17,7 +17,7 @@
* ====================================================================
*/
-package org.jclouds.deltacloud.handlers;
+package org.jclouds.deltacloud.xml;
import static org.testng.Assert.assertEquals;
@@ -26,7 +26,6 @@ import java.net.URI;
import java.util.Map;
import org.jclouds.deltacloud.collections.DeltacloudCollection;
-import org.jclouds.deltacloud.xml.LinksHandler;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
@@ -42,16 +41,17 @@ public class LinksHandlerTest extends BaseHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/links.xml");
-
- Map result = factory.create(injector.getInstance(LinksHandler.class)).parse(is);
- assertEquals(result, ImmutableMap.of(//
+ Map expects = ImmutableMap.of(//
DeltacloudCollection.HARDWARE_PROFILES, URI.create("http://fancycloudprovider.com/api/hardware_profiles"),//
DeltacloudCollection.INSTANCE_STATES, URI.create("http://fancycloudprovider.com/api/instance_states"),//
DeltacloudCollection.REALMS, URI.create("http://fancycloudprovider.com/api/realms"),//
DeltacloudCollection.IMAGES, URI.create("http://fancycloudprovider.com/api/images"),//
DeltacloudCollection.INSTANCES, URI.create("http://fancycloudprovider.com/api/instances")
- ));
+ );
+ // not sure why this isn't always automatically called from surefire.
+ setUpInjector();
+ assertEquals(factory.create(injector.getInstance(LinksHandler.class)).parse(is), expects);
}
diff --git a/sandbox/deltacloud/src/test/resources/log4j.xml b/sandbox/deltacloud/src/test/resources/log4j.xml
new file mode 100644
index 0000000000..7343ec00e2
--- /dev/null
+++ b/sandbox/deltacloud/src/test/resources/log4j.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sandbox/deltacloud/src/test/resources/test_get_instance.xml b/sandbox/deltacloud/src/test/resources/test_get_instance.xml
new file mode 100644
index 0000000000..c3d2245eab
--- /dev/null
+++ b/sandbox/deltacloud/src/test/resources/test_get_instance.xml
@@ -0,0 +1,20 @@
+
+ larry
+ Production JBoss Instance
+
+
+
+
+ RUNNING
+
+
+
+
+
+ inst1.larry.fancycloudprovider.com
+
+
+
+ inst1.larry.internal
+
+
\ No newline at end of file
diff --git a/sandbox/deltacloud/src/test/resources/test_list_instances.xml b/sandbox/deltacloud/src/test/resources/test_list_instances.xml
new file mode 100644
index 0000000000..c8f2dd5eed
--- /dev/null
+++ b/sandbox/deltacloud/src/test/resources/test_list_instances.xml
@@ -0,0 +1,22 @@
+
+
+ larry
+ Production JBoss Instance
+
+
+
+
+ RUNNING
+
+
+
+
+
+ inst1.larry.fancycloudprovider.com
+
+
+
+ inst1.larry.internal
+
+
+
\ No newline at end of file