JcloudsLocation implements SuspendResumeLocation

Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6012a4e4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6012a4e4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6012a4e4

Branch: refs/heads/master
Commit: 6012a4e4cd27db1ccd1495ed1225fcc905d6b0f4
Parents: 1a5e5e7
Author: Sam Corbett <[email protected]>
Authored: Fri Aug 21 10:21:23 2015 +0100
Committer: Sam Corbett <[email protected]>
Committed: Fri Aug 21 10:21:23 2015 +0100

----------------------------------------------------------------------
 .../api/location/MachineManagementMixins.java   |   5 +-
 .../location/jclouds/JcloudsLocation.java       | 130 +++++++++++------
 .../jclouds/AbstractJcloudsLiveTest.java        |  15 ++
 .../JcloudsLocationRebindMachineLiveTest.java   | 138 ------------------
 .../JcloudsLocationRegisterMachineLiveTest.java | 144 +++++++++++++++++++
 ...udsLocationSuspendResumeMachineLiveTest.java |  62 ++++++++
 6 files changed, 311 insertions(+), 183 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
 
b/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
index b91aeb8..f7c091b 100644
--- 
a/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
+++ 
b/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
@@ -70,8 +70,7 @@ public class MachineManagementMixins {
      * Implement to indicate that a location can suspend and resume machines.
      */
     @Beta
-    public interface SuspendResumeLocation extends SuspendsMachines, 
ResumesMachines {};
-
+    public interface SuspendResumeLocation extends SuspendsMachines, 
ResumesMachines {}
 
     @Beta
     public interface SuspendsMachines {
@@ -86,7 +85,7 @@ public class MachineManagementMixins {
         /**
          * Resume the indicated machine.
          */
-        void resumeMachine(MachineLocation location);
+        MachineLocation resumeMachine(Map<?, ?> flags);
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index 21d4760..6b960d3 100644
--- 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -189,7 +189,7 @@ import io.cloudsoft.winrm4j.pywinrm.WinRMFactory;
 @SuppressWarnings("serial")
 public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation 
implements
         JcloudsLocationConfig, 
MachineManagementMixins.RichMachineProvisioningLocation<MachineLocation>,
-        LocationWithObjectStore, MachineManagementMixins.SuspendsMachines {
+        LocationWithObjectStore, MachineManagementMixins.SuspendResumeLocation 
{
 
     // TODO After converting from Groovy to Java, this is now very bad code! 
It relies entirely on putting
     // things into and taking them out of maps; it's not type-safe, and it's 
thus very error-prone.
@@ -514,7 +514,11 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         ConfigBag conf = (flags==null || flags.isEmpty())
                 ? config().getBag()
                 : ConfigBag.newInstanceExtending(config().getBag(), flags);
-        return getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(conf, 
true);
+        return getComputeService(conf);
+    }
+
+    public ComputeService getComputeService(ConfigBag config) {
+        return getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(config, 
true);
     }
 
     /** @deprecated since 0.7.0 use {@link #listMachines()} */ @Deprecated
@@ -1054,6 +1058,32 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         }
     }
 
+    /**
+     * Brings an existing machine with the given details under management.
+     * <p/>
+     * Note that this method does <b>not</b> call the lifecycle methods of any
+     * {@link #getCustomizers(ConfigBag) customizers} attached to this 
location.
+     *
+     * @param flags See {@link #registerMachine(ConfigBag)} for a description 
of required fields.
+     * @see #registerMachine(ConfigBag)
+     */
+    @Override
+    public MachineLocation resumeMachine(Map<?, ?> flags) {
+        ConfigBag setup = ConfigBag.newInstanceExtending(config().getBag(), 
flags);
+        LOG.info("{} using resuming node matching properties: {}", this, 
setup);
+        ComputeService computeService = getComputeService(setup);
+        NodeMetadata node = findNodeOrThrow(setup);
+        LOG.debug("{} resuming {}", this, node);
+        computeService.resumeNode(node.getId());
+        // Load the node a second time once it is resumed to get an object with
+        // hostname and addresses populated.
+        node = findNodeOrThrow(setup);
+        LOG.debug("{} resumed {}", this, node);
+        MachineLocation registered = registerMachineLocation(setup, node);
+        LOG.info("{} resumed and registered {}", this, registered);
+        return registered;
+    }
+
     // ------------- constructing the template, etc ------------------------
 
     private static interface CustomizeTemplateBuilder {
@@ -1871,7 +1901,7 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         return (JcloudsSshMachineLocation) registerMachine(metadata);
     }
 
-    public MachineLocation registerMachine(NodeMetadata metadata) throws 
NoMachinesAvailableException {
+    protected MachineLocation registerMachine(NodeMetadata metadata) throws 
NoMachinesAvailableException {
         return registerMachine(MutableMap.of(), metadata);
     }
 
@@ -1883,7 +1913,7 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
         return (JcloudsSshMachineLocation) registerMachine(flags, metadata);
     }
 
-    public MachineLocation registerMachine(Map<?, ?> flags, NodeMetadata 
metadata) throws NoMachinesAvailableException {
+    protected MachineLocation registerMachine(Map<?, ?> flags, NodeMetadata 
metadata) throws NoMachinesAvailableException {
         ConfigBag setup = ConfigBag.newInstanceExtending(config().getBag(), 
flags);
         if (!setup.containsKey("id")) setup.putStringKey("id", 
metadata.getId());
         setHostnameUpdatingCredentials(setup, metadata);
@@ -1891,6 +1921,9 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
     }
 
     /**
+     * Brings an existing machine with the given details under management.
+     * <p>
+     * This method will throw an exception if used to reconnect to a Windows 
VM.
      * @deprecated since 0.8.0 use {@link #registerMachine(ConfigBag)} instead.
      */
     @Deprecated
@@ -1905,54 +1938,67 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
      * <ul>
      *   <li>id: the jclouds VM id, e.g. "eu-west-1/i-5504f21d" (NB this is 
{@see JcloudsMachineLocation#getJcloudsId()} not #getId())
      *   <li>hostname: the public hostname or IP of the machine, e.g. 
"ec2-176-34-93-58.eu-west-1.compute.amazonaws.com"
-     *   <li>userName: the username for sshing into the machine if it is not a 
Windows system
+     *   <li>userName: the username for sshing into the machine (for use if it 
is not a Windows system)
      * <ul>
      */
     public MachineLocation registerMachine(ConfigBag setup) throws 
NoMachinesAvailableException {
-        try {
-            if (setup.getDescription() == null) setCreationString(setup);
-            String user = checkNotNull(getUser(setup), "user");
-            String rawId = (String) setup.getStringKey("id");
-            String rawHostname = (String) setup.getStringKey("hostname");
-            Predicate<ComputeMetadata> predicate = 
getRebindToMachinePredicate(setup);
-            LOG.info("Rebinding to VM {} ({}@{}), in jclouds location for 
provider {} matching {}", new Object[]{
-                    rawId != null ? rawId : "<lookup>",
-                    user,
-                    rawHostname != null ? rawHostname : "<unspecified>",
-                    getProvider(),
-                    predicate
-                    });
-            ComputeService computeService = 
getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(setup, true);
-            Set<? extends NodeMetadata> candidateNodes = 
computeService.listNodesDetailsMatching(predicate);
-            if (candidateNodes.isEmpty()) {
-                throw new IllegalArgumentException("Jclouds node not found for 
rebind with predicate " + predicate);
-            } else if (candidateNodes.size() > 1) {
-                throw new IllegalArgumentException("Jclouds node for rebind 
matched multiple with " + predicate + ": " + candidateNodes);
-            }
-
-            NodeMetadata node = Iterables.getOnlyElement(candidateNodes);
-            String pkd = 
LocationConfigUtils.getOsCredential(setup).checkNoErrors().logAnyWarnings().getPrivateKeyData();
-            if (Strings.isNonBlank(pkd)) {
-                LoginCredentials expectedCredentials = 
LoginCredentials.fromCredentials(new Credentials(user, pkd));
-                //override credentials
-                node = 
NodeMetadataBuilder.fromNodeMetadata(node).credentials(expectedCredentials).build();
-            }
-
-            // TODO confirm we can SSH ?
-            // NB if rawHostname not set, get the hostname using 
getPublicHostname(node, Optional.<HostAndPort>absent(), setup);
+        NodeMetadata node = findNodeOrThrow(setup);
+        return registerMachineLocation(setup, node);
+    }
 
-            if (isWindows(node, setup)) {
-                return registerWinRmMachineLocation(computeService, node, 
null, Optional.<HostAndPort>absent(), setup);
-            } else {
+    protected MachineLocation registerMachineLocation(ConfigBag setup, 
NodeMetadata node) {
+        ComputeService computeService = getComputeService(setup);
+        if (isWindows(node, setup)) {
+            return registerWinRmMachineLocation(computeService, node, null, 
Optional.<HostAndPort>absent(), setup);
+        } else {
+            try {
                 return registerJcloudsSshMachineLocation(computeService, node, 
null, Optional.<HostAndPort>absent(), setup);
+            } catch (IOException e) {
+                throw Exceptions.propagate(e);
             }
-
-        } catch (IOException e) {
-            throw Exceptions.propagate(e);
         }
     }
 
     /**
+     * Finds a node matching the properties given in config or throws an 
exception.
+     * @param config
+     * @return
+     */
+    protected NodeMetadata findNodeOrThrow(ConfigBag config) {
+        if (config.getDescription() == null) {
+            setCreationString(config);
+        }
+        String user = checkNotNull(getUser(config), "user");
+        String rawId = (String) config.getStringKey("id");
+        String rawHostname = (String) config.getStringKey("hostname");
+        Predicate<ComputeMetadata> predicate = 
getRebindToMachinePredicate(config);
+        LOG.debug("Finding VM {} ({}@{}), in jclouds location for provider {} 
matching {}", new Object[]{
+                rawId != null ? rawId : "<lookup>",
+                user,
+                rawHostname != null ? rawHostname : "<unspecified>",
+                getProvider(),
+                predicate
+        });
+        ComputeService computeService = getComputeService(config);
+        Set<? extends NodeMetadata> candidateNodes = 
computeService.listNodesDetailsMatching(predicate);
+        if (candidateNodes.isEmpty()) {
+            throw new IllegalArgumentException("Jclouds node not found for 
rebind with predicate " + predicate);
+        } else if (candidateNodes.size() > 1) {
+            throw new IllegalArgumentException("Jclouds node for rebind 
matched multiple with " + predicate + ": " + candidateNodes);
+        }
+        NodeMetadata node = Iterables.getOnlyElement(candidateNodes);
+
+        String pkd = 
LocationConfigUtils.getOsCredential(config).checkNoErrors().logAnyWarnings().getPrivateKeyData();
+        if (Strings.isNonBlank(pkd)) {
+            LoginCredentials expectedCredentials = 
LoginCredentials.fromCredentials(new Credentials(user, pkd));
+            //override credentials
+            node = 
NodeMetadataBuilder.fromNodeMetadata(node).credentials(expectedCredentials).build();
+        }
+
+        return node;
+    }
+
+    /**
      * @deprecated since 0.8.0 use {@link #registerMachine(Map)} instead.
      */
     @Deprecated

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
index 4061ea3..13138a5 100644
--- 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;
@@ -154,4 +155,18 @@ public class AbstractJcloudsLiveTest {
         machines.remove(machine);
         jcloudsLocation.release(machine);
     }
+
+    protected void suspendMachine(MachineLocation machine) {
+        assertNotNull(jcloudsLocation);
+        machines.remove(machine);
+        jcloudsLocation.suspendMachine(machine);
+    }
+
+    protected MachineLocation resumeMachine(Map<?, ?> flags) {
+        assertNotNull(jcloudsLocation);
+        MachineLocation location = jcloudsLocation.resumeMachine(flags);
+        machines.add((JcloudsSshMachineLocation) location);
+        return location;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
deleted file mode 100644
index 6d891a6..0000000
--- 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.location.jclouds;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.net.InetAddress;
-import java.util.Collections;
-
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class JcloudsLocationRebindMachineLiveTest extends 
AbstractJcloudsLiveTest {
-    
-    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsLocationRebindMachineLiveTest.class);
-    
-    private static final String EUWEST_IMAGE_ID = 
AWS_EC2_EUWEST_REGION_NAME+"/"+"ami-89def4fd";
-    private static final String IMAGE_OWNER = "411009282317";
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        jcloudsLocation = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-    }
-
-    @Test(groups = { "Live", "Live-sanity" })
-    public void testRebindWithIncorrectId() throws Exception {
-        try {
-            jcloudsLocation.registerMachine(ImmutableMap.of("id", 
"incorrectid", "hostname", "myhostname", "user", "myusername"));
-        } catch (IllegalArgumentException e) {
-            if (e.getMessage().contains("node not found")) {
-                // success
-            } else {
-                throw e;
-            }
-        }
-    }
-    
-    @Test(groups = { "Live" })
-    public void testRebindVm() throws Exception {
-        // FIXME How to create a machine - go directly through jclouds instead?
-        //       Going through LocationRegistry.resolve, loc and loc2 might be 
same instance
-        
-        // Create a VM through jclouds
-        JcloudsSshMachineLocation machine = 
obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", 
IMAGE_OWNER));
-        assertTrue(machine.isSshable());
-        LOG.info("obtained "+machine);
-
-        String id = checkNotNull(machine.getJcloudsId(), "id");
-        InetAddress address = checkNotNull(machine.getAddress(), "address");
-        String hostname = checkNotNull(address.getHostName(), "hostname");
-        String user = checkNotNull(machine.getUser(), "user");
-        
-        // Create a new jclouds location, and re-bind the existing VM to that
-        JcloudsLocation loc2 = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", 
id, "hostname", hostname, "user", user));
-        
-        LOG.info("rebinded to "+machine2);
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine2.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
ImmutableSet.of(machine2));
-        
-        // Confirm can release the re-bound machine via the new jclouds 
location
-        loc2.release(machine2);
-        assertFalse(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
Collections.emptySet());
-    }
-    
-    @Test(groups = { "Live" })
-    public void testRebindVmDeprecated() throws Exception {
-        // FIXME See comments in testRebindVm
-
-        // Create a VM through jclouds
-        JcloudsSshMachineLocation machine = 
obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", 
IMAGE_OWNER));
-        assertTrue(machine.isSshable());
-
-        String id = machine.getJcloudsId();
-        InetAddress address = machine.getAddress();
-        String hostname = address.getHostName();
-        String username = machine.getUser();
-        
-        // Create a new jclouds location, and re-bind the existing VM to that
-        JcloudsLocation loc2 = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-        // pass deprecated userName
-        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", 
id, "hostname", hostname, "userName", username));
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine2.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
ImmutableSet.of(machine2));
-        
-        // Confirm can release the re-bound machine via the new jclouds 
location
-        loc2.release(machine2);
-        assertFalse(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
Collections.emptySet());
-    }
-
-    // Useful for debugging; accesss a hard-coded existing instance so don't 
need to wait for provisioning a new one
-    @Test(enabled=false, groups = { "Live" })
-    public void testRebindVmToHardcodedInstance() throws Exception {
-        String id = "eu-west-1/i-5504f21d";
-        InetAddress address = 
InetAddress.getByName("ec2-176-34-93-58.eu-west-1.compute.amazonaws.com");
-        String hostname = address.getHostName();
-        String username = "root";
-        
-        SshMachineLocation machine = 
jcloudsLocation.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, 
"userName", username));
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(jcloudsLocation.getChildren()), 
ImmutableSet.of(machine));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRegisterMachineLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRegisterMachineLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRegisterMachineLiveTest.java
new file mode 100644
index 0000000..e7d7d36
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRegisterMachineLiveTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.net.InetAddress;
+import java.util.Collections;
+
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class JcloudsLocationRegisterMachineLiveTest extends 
AbstractJcloudsLiveTest {
+    
+    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsLocationRegisterMachineLiveTest.class);
+    
+    private static final String EUWEST_IMAGE_ID = 
AWS_EC2_EUWEST_REGION_NAME+"/"+"ami-ce7b6fba";
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        jcloudsLocation = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+    }
+
+    @Test(groups = { "Live", "Live-sanity" })
+    public void testRegisterWithIncorrectId() throws Exception {
+        try {
+            jcloudsLocation.registerMachine(ImmutableMap.of("id", 
"incorrectid", "hostname", "myhostname", "user", "myusername"));
+        } catch (IllegalArgumentException e) {
+            if (e.getMessage().contains("node not found")) {
+                // success
+            } else {
+                throw e;
+            }
+        }
+    }
+    
+    @Test(groups = { "Live" })
+    public void testRegisterVm() throws Exception {
+        // FIXME How to create a machine - go directly through jclouds instead?
+        //       Going through LocationRegistry.resolve, loc and loc2 might be 
same instance
+        
+        // Create a VM through jclouds
+        JcloudsSshMachineLocation machine = 
obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID));
+        assertTrue(machine.isSshable());
+        LOG.info("obtained "+machine);
+
+        String id = checkNotNull(machine.getJcloudsId(), "id");
+        InetAddress address = checkNotNull(machine.getAddress(), "address");
+        String hostname = checkNotNull(address.getHostName(), "hostname");
+        String user = checkNotNull(machine.getUser(), "user");
+        
+        // Create a new jclouds location, and re-bind the existing VM to that
+        JcloudsLocation loc2 = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+        MachineLocation machineLocation = 
loc2.registerMachine(ImmutableMap.of("id", id, "hostname", hostname, "user", 
user));
+        assertTrue(machineLocation instanceof SshMachineLocation);
+        SshMachineLocation machine2 = (SshMachineLocation) machineLocation;
+
+        LOG.info("Registered " + machine2);
+        
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine2.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
ImmutableSet.of(machine2));
+        
+        // Confirm can release the re-bound machine via the new jclouds 
location
+        loc2.release(machine2);
+        assertFalse(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
Collections.emptySet());
+    }
+    
+    @Test(groups = { "Live" })
+    public void testRegisterVmDeprecated() throws Exception {
+        // FIXME See comments in testRegisterVm
+
+        // Create a VM through jclouds
+        JcloudsSshMachineLocation machine = 
obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID));
+        assertTrue(machine.isSshable());
+
+        String id = machine.getJcloudsId();
+        InetAddress address = machine.getAddress();
+        String hostname = address.getHostName();
+        String username = machine.getUser();
+        
+        // Create a new jclouds location, and re-bind the existing VM to that
+        JcloudsLocation loc2 = (JcloudsLocation) 
managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+        // pass deprecated userName
+        MachineLocation machineLocation = 
loc2.registerMachine(ImmutableMap.of("id", id, "hostname", hostname, 
"userName", username));
+        assertTrue(machineLocation instanceof SshMachineLocation);
+        SshMachineLocation machine2 = (SshMachineLocation) machineLocation;
+
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine2.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
ImmutableSet.of(machine2));
+        
+        // Confirm can release the re-bound machine via the new jclouds 
location
+        loc2.release(machine2);
+        assertFalse(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), 
Collections.emptySet());
+    }
+
+    // Useful for debugging; accesss a hard-coded existing instance so don't 
need to wait for provisioning a new one
+    @Test(enabled=false, groups = { "Live" })
+    public void testRegisterVmToHardcodedInstance() throws Exception {
+        String id = "eu-west-1/i-5504f21d";
+        InetAddress address = 
InetAddress.getByName("ec2-176-34-93-58.eu-west-1.compute.amazonaws.com");
+        String hostname = address.getHostName();
+        String username = "root";
+        
+        MachineLocation machineLocation = 
jcloudsLocation.registerMachine(ImmutableMap.of("id", id, "hostname", hostname, 
"userName", username));
+        assertTrue(machineLocation instanceof SshMachineLocation);
+        SshMachineLocation machine = (SshMachineLocation) machineLocation;
+
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(jcloudsLocation.getChildren()), 
ImmutableSet.of(machine));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6012a4e4/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationSuspendResumeMachineLiveTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationSuspendResumeMachineLiveTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationSuspendResumeMachineLiveTest.java
new file mode 100644
index 0000000..048a563
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationSuspendResumeMachineLiveTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class JcloudsLocationSuspendResumeMachineLiveTest extends 
AbstractJcloudsLiveTest {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(JcloudsLocationSuspendResumeMachineLiveTest.class);
+
+    private static final String EUWEST_IMAGE_ID = AWS_EC2_EUWEST_REGION_NAME + 
"/" + "ami-ce7b6fba";
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        jcloudsLocation = (JcloudsLocation) 
managementContext.getLocationRegistry()
+                .resolve(AWS_EC2_PROVIDER + ":" + AWS_EC2_EUWEST_REGION_NAME);
+    }
+
+    @Test(groups = "Live")
+    public void testObtainThenSuspendThenResumeMachine() throws Exception {
+        MachineLocation machine = obtainMachine(ImmutableMap.of(
+                "imageId", EUWEST_IMAGE_ID));
+        JcloudsSshMachineLocation sshMachine = (JcloudsSshMachineLocation) 
machine;
+        assertTrue(sshMachine.isSshable(), "Cannot SSH to " + sshMachine);
+
+        suspendMachine(machine);
+        assertFalse(sshMachine.isSshable(), "Should not be able to SSH to 
suspended machine");
+
+        MachineLocation machine2 = resumeMachine(ImmutableMap.of("id", 
sshMachine.getJcloudsId()));
+        assertTrue(machine2 instanceof JcloudsSshMachineLocation);
+        assertTrue(((JcloudsSshMachineLocation) machine2).isSshable(), "Cannot 
SSH to " + machine2);
+    }
+
+}

Reply via email to