You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/07/01 21:13:19 UTC

[14/20] JCLOUDS-150 - Removal of async from AWS - specifically EC2

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
deleted file mode 100644
index 3b8bd75..0000000
--- a/apis/ec2/src/test/java/org/jclouds/ec2/EBSBootEC2ClientLiveTest.java
+++ /dev/null
@@ -1,607 +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.jclouds.ec2;
-
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.jclouds.ec2.options.CreateSnapshotOptions.Builder.withDescription;
-import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds;
-import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.withKernelId;
-import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKeyName;
-import static org.jclouds.util.Predicates2.retry;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.net.UnknownHostException;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-import org.jclouds.aws.AWSResponseException;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.ec2.domain.Attachment;
-import org.jclouds.ec2.domain.BlockDevice;
-import org.jclouds.ec2.domain.Image;
-import org.jclouds.ec2.domain.Image.Architecture;
-import org.jclouds.ec2.domain.Image.ImageType;
-import org.jclouds.ec2.domain.InstanceState;
-import org.jclouds.ec2.domain.InstanceType;
-import org.jclouds.ec2.domain.KeyPair;
-import org.jclouds.ec2.domain.Reservation;
-import org.jclouds.ec2.domain.RootDeviceType;
-import org.jclouds.ec2.domain.RunningInstance;
-import org.jclouds.ec2.domain.Snapshot;
-import org.jclouds.ec2.domain.Volume;
-import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior;
-import org.jclouds.ec2.predicates.InstanceStateRunning;
-import org.jclouds.ec2.predicates.InstanceStateStopped;
-import org.jclouds.ec2.predicates.InstanceStateTerminated;
-import org.jclouds.ec2.predicates.SnapshotCompleted;
-import org.jclouds.ec2.predicates.VolumeAttached;
-import org.jclouds.ec2.predicates.VolumeAvailable;
-import org.jclouds.http.HttpResponseException;
-import org.jclouds.io.Payloads;
-import org.jclouds.net.domain.IpProtocol;
-import org.jclouds.predicates.SocketOpen;
-import org.jclouds.scriptbuilder.InitScript;
-import org.jclouds.scriptbuilder.domain.OsFamily;
-import org.jclouds.scriptbuilder.domain.Statements;
-import org.jclouds.ssh.SshClient;
-import org.jclouds.ssh.SshException;
-import org.testng.annotations.AfterTest;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.net.HostAndPort;
-import com.google.inject.Injector;
-
-/**
- * Adapted from the following sources: {@link http://gist.github.com/249915}, {@link http
- * ://www.capsunlock.net/2009/12/create-ebs-boot-ami.html}
- * <p/>
- * 
- * Generally disabled, as it incurs higher fees.
- * 
- * @author Adrian Cole
- */
-@Test(groups = "live", enabled = false, singleThreaded = true, testName = "EBSBootEC2ClientLiveTest")
-public class EBSBootEC2ClientLiveTest extends BaseComputeServiceContextLiveTest {
-   public EBSBootEC2ClientLiveTest() {
-      provider = "ec2";
-   }
-
-   // TODO: parameterize
-   private static final String IMAGE_ID = "ami-7e28ca17";
-
-   // don't need a lot of space. 2GB should be more than enough for testing
-   private static final int VOLUME_SIZE = 2;
-   private static final String SCRIPT_END = "----COMPLETE----";
-   private static final String INSTANCE_PREFIX = System.getProperty("user.name") + ".ec2ebs";
-
-   private EC2Client client;
-   private SshClient.Factory sshFactory;
-
-   private KeyPair keyPair;
-   private String securityGroupName;
-
-   private Predicate<HostAndPort> socketTester;
-   private Predicate<Attachment> attachTester;
-   private Predicate<Volume> volumeTester;
-   private RunningInstance instance;
-   private Predicate<RunningInstance> runningTester;
-   private Predicate<RunningInstance> stoppedTester;
-   private Predicate<RunningInstance> terminatedTester;
-   private Volume volume;
-   private Predicate<Snapshot> snapshotTester;
-   private Snapshot snapshot;
-   private Image ebsImage;
-   private RunningInstance ebsInstance;
-   private Attachment attachment;
-   private String mkEbsBoot;
-
-   @Override
-   @BeforeClass(groups = { "integration", "live" })
-   public void setupContext() {
-      super.setupContext();
-      Injector injector = view.utils().injector();
-      client = injector.getInstance(EC2Client.class);
-      sshFactory = injector.getInstance(SshClient.Factory.class);
-      SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
-      socketTester = retry(socketOpen, 120, 1, SECONDS);
-
-      VolumeAvailable volumeAvailable = injector.getInstance(VolumeAvailable.class);
-      volumeTester = retry(volumeAvailable, 60, 1, SECONDS);
-
-      SnapshotCompleted snapshotCompleted = injector.getInstance(SnapshotCompleted.class);
-      snapshotTester = retry(snapshotCompleted, 120, 3, SECONDS);
-
-      VolumeAttached volumeAttached = injector.getInstance(VolumeAttached.class);
-      attachTester = retry(volumeAttached, 60, 1, SECONDS);
-
-      runningTester = retry(new InstanceStateRunning(client), 180, 5, SECONDS);
-
-      InstanceStateStopped instanceStateStopped = injector.getInstance(InstanceStateStopped.class);
-      stoppedTester = retry(instanceStateStopped, 60, 1, SECONDS);
-
-      InstanceStateTerminated instanceStateTerminated = injector.getInstance(InstanceStateTerminated.class);
-      terminatedTester = retry(instanceStateTerminated, 60, 1, SECONDS);
-
-      injector.injectMembers(socketOpen); // add logger
-   }
-
-   @Test(enabled = false)
-   void testCreateSecurityGroupIngressCidr() throws InterruptedException, ExecutionException, TimeoutException {
-      securityGroupName = INSTANCE_PREFIX + "ingress";
-
-      try {
-         client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
-      } catch (Exception e) {
-      }
-
-      client.getSecurityGroupServices().createSecurityGroupInRegion(null, securityGroupName, securityGroupName);
-      client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null, securityGroupName, IpProtocol.TCP,
-            80, 80, "0.0.0.0/0");
-      client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null, securityGroupName, IpProtocol.TCP,
-            443, 443, "0.0.0.0/0");
-      client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null, securityGroupName, IpProtocol.TCP,
-            22, 22, "0.0.0.0/0");
-   }
-
-   @Test(enabled = false)
-   void testCreateKeyPair() {
-      String keyName = INSTANCE_PREFIX + "1";
-      try {
-         client.getKeyPairServices().deleteKeyPairInRegion(null, keyName);
-      } catch (Exception e) {
-
-      }
-
-      keyPair = client.getKeyPairServices().createKeyPairInRegion(null, keyName);
-      assertNotNull(keyPair);
-      assertNotNull(keyPair.getKeyMaterial());
-      assertNotNull(keyPair.getSha1OfPrivateKey());
-      assertEquals(keyPair.getKeyName(), keyName);
-   }
-
-   @Test(enabled = false, dependsOnMethods = { "testCreateKeyPair", "testCreateSecurityGroupIngressCidr" })
-   public void testCreateRunningInstance() throws Exception {
-      instance = createInstance(IMAGE_ID);
-   }
-
-   private RunningInstance createInstance(String imageId) throws UnknownHostException {
-      RunningInstance instance = null;
-      while (instance == null) {
-         try {
-            System.out.printf("%d: running instance%n", System.currentTimeMillis());
-            Reservation<? extends RunningInstance> reservation = client.getInstanceServices().runInstancesInRegion(
-                  null, null, // allow
-                  // ec2
-                  // to
-                  // chose
-                  // an
-                  // availability
-                  // zone
-                  imageId, 1, // minimum instances
-                  1, // maximum instances
-                  withKeyName(keyPair.getKeyName())// key I created above
-                        .asType(InstanceType.M1_SMALL)// smallest instance
-                        // size
-                        .withSecurityGroup(securityGroupName));// group I
-            // created
-            // above
-            instance = Iterables.getOnlyElement(reservation);
-         } catch (HttpResponseException htpe) {
-            if (htpe.getResponse().getStatusCode() == 400)
-               continue;
-            throw htpe;
-         }
-      }
-      assertNotNull(instance.getId());
-      assertEquals(instance.getInstanceState(), InstanceState.PENDING);
-      instance = blockUntilWeCanSshIntoInstance(instance);
-      return instance;
-   }
-
-   @Test(enabled = false, dependsOnMethods = "testCreateRunningInstance")
-   void testCreateAndAttachVolume() {
-      volume = client.getElasticBlockStoreServices().createVolumeInAvailabilityZone(instance.getAvailabilityZone(),
-            VOLUME_SIZE);
-      System.out.printf("%d: %s awaiting volume to become available%n", System.currentTimeMillis(), volume.getId());
-
-      assert volumeTester.apply(volume);
-
-      Attachment attachment = client.getElasticBlockStoreServices().attachVolumeInRegion(instance.getRegion(),
-            volume.getId(), instance.getId(), "/dev/sdh");
-
-      System.out.printf("%d: %s awaiting attachment to complete%n", System.currentTimeMillis(), attachment.getId());
-
-      assert attachTester.apply(attachment);
-      System.out.printf("%d: %s attachment complete%n", System.currentTimeMillis(), attachment.getId());
-   }
-
-   // TODO use userData to do this, and make initbuilder an example for
-   // something else.
-   @BeforeTest
-   void makeScript() {
-
-      mkEbsBoot = InitScript.builder()
-            .name("mkebsboot")
-            .home("/tmp")
-            .logDir("/tmp/logs")
-            .exportVariables(ImmutableMap.of("imageDir", "/mnt/tmp", "ebsDevice", "/dev/sdh", "ebsMountPoint", "/mnt/ebs"))
-            .run(Statements
-                  .interpret(
-                        "echo creating a filesystem and mounting the ebs volume",
-                        "{md} {varl}IMAGE_DIR{varr} {varl}EBS_MOUNT_POINT{varr}",
-                        "rm -rf {varl}IMAGE_DIR{varr}/*",
-                        "yes| mkfs -t ext3 {varl}EBS_DEVICE{varr} 2>&-",
-                        "mount {varl}EBS_DEVICE{varr} {varl}EBS_MOUNT_POINT{varr}",
-                        "echo making a local working copy of the boot disk",
-                        "rsync -ax --exclude /ubuntu/.bash_history --exclude /home/*/.bash_history --exclude /etc/ssh/ssh_host_* --exclude /etc/ssh/moduli --exclude /etc/udev/rules.d/*persistent-net.rules --exclude /var/lib/* --exclude=/mnt/* --exclude=/proc/* --exclude=/tmp/* --exclude=/dev/log / {varl}IMAGE_DIR{varr}",
-                        "echo preparing the local working copy",
-                        "touch {varl}IMAGE_DIR{varr}/etc/init.d/ec2-init-user-data",
-                        "echo copying the local working copy to the ebs mount", "{cd} {varl}IMAGE_DIR{varr}",
-                        "tar -cSf - * | tar xf - -C {varl}EBS_MOUNT_POINT{varr}", "echo size of ebs",
-                        "du -sk {varl}EBS_MOUNT_POINT{varr}", "echo size of source", "du -sk {varl}IMAGE_DIR{varr}",
-                        "rm -rf {varl}IMAGE_DIR{varr}/*", "umount {varl}EBS_MOUNT_POINT{varr}", "echo " + SCRIPT_END)).build()
-            .render(OsFamily.UNIX);
-   }
-
-   @Test(enabled = false, dependsOnMethods = "testCreateAndAttachVolume")
-   void testBundleInstance() {
-      SshClient ssh = sshFactory.create(HostAndPort.fromParts(instance.getIpAddress(), 22),
-            LoginCredentials.builder().user("ubuntu").privateKey(keyPair.getKeyMaterial()).build());
-      try {
-         ssh.connect();
-      } catch (SshException e) {// try twice in case there is a network timeout
-         try {
-            Thread.sleep(10 * 1000);
-         } catch (InterruptedException e1) {
-         }
-         ssh.connect();
-      }
-      try {
-         System.out.printf("%d: %s writing ebs script%n", System.currentTimeMillis(), instance.getId());
-         String script = "/tmp/mkebsboot-init.sh";
-         ssh.put(script, Payloads.newStringPayload(mkEbsBoot));
-
-         System.out.printf("%d: %s launching ebs script%n", System.currentTimeMillis(), instance.getId());
-         ssh.exec("chmod 755 " + script);
-         ssh.exec(script + " init");
-         ExecResponse output = ssh.exec("sudo " + script + " start");
-         System.out.println(output);
-         output = ssh.exec(script + " status");
-
-         assert !output.getOutput().trim().equals("") : output;
-         Predicate<String> scriptTester = retry(new ScriptTester(ssh, SCRIPT_END), 600, 10, SECONDS);
-         scriptTester.apply(script);
-      } finally {
-         if (ssh != null)
-            ssh.disconnect();
-      }
-   }
-
-   public static class ScriptTester implements Predicate<String> {
-      private final SshClient ssh;
-      private final String endMatches;
-
-      public ScriptTester(SshClient ssh, String endMatches) {
-         this.ssh = ssh;
-         this.endMatches = endMatches;
-      }
-
-      @Override
-      public boolean apply(String script) {
-         System.out.printf("%d: %s testing status%n", System.currentTimeMillis(), script);
-         ExecResponse output = ssh.exec(script + " status");
-         if (output.getOutput().trim().equals("")) {
-            output = ssh.exec(script + " tail");
-            String stdout = output.getOutput().trim();
-            if (stdout.contains(endMatches)) {
-               return true;
-            } else {
-               output = ssh.exec(script + " tailerr");
-               String stderr = output.getOutput().trim();
-               throw new RuntimeException(String.format(
-                     "script %s ended without token: stdout.log: [%s]; stderr.log: [%s]; ", script, stdout, stderr));
-            }
-         }
-         return false;
-      }
-
-   }
-
-   @Test(enabled = false, dependsOnMethods = "testBundleInstance")
-   void testAMIFromBundle() {
-      volume = Iterables.getOnlyElement(client.getElasticBlockStoreServices().describeVolumesInRegion(
-            volume.getRegion(), volume.getId()));
-      if (volume.getAttachments().size() > 0) {
-         // should be cleanly unmounted, so force is not necessary.
-         client.getElasticBlockStoreServices().detachVolumeInRegion(instance.getRegion(), volume.getId(), false);
-         System.out.printf("%d: %s awaiting detachment to complete%n", System.currentTimeMillis(), volume.getId());
-         assert volumeTester.apply(volume);
-      } else {
-         attachment = null; // protect test closer so that it doesn't try to
-         // detach
-      }
-      snapshot = client.getElasticBlockStoreServices().createSnapshotInRegion(volume.getRegion(), volume.getId(),
-            withDescription("EBS Ubuntu Hardy"));
-
-      System.out.printf("%d: %s awaiting snapshot to complete%n", System.currentTimeMillis(), snapshot.getId());
-
-      assert snapshotTester.apply(snapshot);
-      Image image = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(snapshot.getRegion(),
-            imageIds(IMAGE_ID)));
-      String description = image.getDescription() == null ? "jclouds" : image.getDescription();
-
-      System.out.printf("%d: %s creating ami from snapshot%n", System.currentTimeMillis(), snapshot.getId());
-
-      String amiId = client.getAMIServices().registerUnixImageBackedByEbsInRegion(
-            snapshot.getRegion(),
-            "ebsboot-" + image.getId(),
-            snapshot.getId(),
-            withKernelId(image.getKernelId()).withRamdisk(image.getRamdiskId()).withDescription(description)
-                  .asArchitecture(Architecture.I386));
-      try {
-         ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(snapshot.getRegion(),
-               imageIds(amiId)));
-      } catch (AWSResponseException e) {
-         // TODO add a retry handler for this HTTP code 400 and the below error
-         if (e.getError().getClass().equals("InvalidAMIID.NotFound"))
-            ebsImage = Iterables.getOnlyElement(client.getAMIServices().describeImagesInRegion(snapshot.getRegion(),
-                  imageIds(amiId)));
-         else
-            throw e;
-      }
-      verifyImage();
-   }
-
-   @Test(enabled = false, dependsOnMethods = { "testAMIFromBundle" })
-   public void testInstanceFromEBS() throws Exception {
-      System.out.printf("%d: %s creating instance from ebs-backed ami%n", System.currentTimeMillis(), ebsImage.getId());
-
-      ebsInstance = createInstance(ebsImage.getId());
-
-      client.getInstanceServices().stopInstancesInRegion(ebsInstance.getRegion(), true, ebsInstance.getId());
-
-      System.out.printf("%d: %s awaiting instance to stop %n", System.currentTimeMillis(), ebsInstance.getId());
-      stoppedTester.apply(ebsInstance);
-      tryToChangeStuff();
-      System.out.printf("%d: %s awaiting instance to start %n", System.currentTimeMillis(), ebsInstance.getId());
-      client.getInstanceServices().startInstancesInRegion(ebsInstance.getRegion(), ebsInstance.getId());
-      ebsInstance = blockUntilWeCanSshIntoInstance(ebsInstance);
-   }
-
-   private void verifyImage() {
-      assertEquals(ebsImage.getImageType(), ImageType.MACHINE);
-      assertEquals(ebsImage.getRootDeviceType(), RootDeviceType.EBS);
-      assertEquals(ebsImage.getRootDeviceName(), "/dev/sda1");
-      assertEquals(ebsImage.getEbsBlockDevices().entrySet(),
-            ImmutableMap.of("/dev/sda1", new Image.EbsBlockDevice(snapshot.getId(), VOLUME_SIZE, true)).entrySet());
-   }
-
-   private void tryToChangeStuff() {
-      setUserDataForInstanceInRegion();
-      setRamdiskForInstanceInRegion();
-      setKernelForInstanceInRegion();
-      setInstanceTypeForInstanceInRegion();
-      setInstanceInitiatedShutdownBehaviorForInstanceInRegion();
-      setBlockDeviceMappingForInstanceInRegion();
-   }
-
-   private void setUserDataForInstanceInRegion() {
-      client.getInstanceServices().setUserDataForInstanceInRegion(null, ebsInstance.getId(), "test".getBytes());
-      assertEquals("test", client.getInstanceServices().getUserDataForInstanceInRegion(null, ebsInstance.getId()));
-   }
-
-   private void setRamdiskForInstanceInRegion() {
-      String ramdisk = client.getInstanceServices().getRamdiskForInstanceInRegion(null, ebsInstance.getId());
-      client.getInstanceServices().setRamdiskForInstanceInRegion(null, ebsInstance.getId(), ramdisk);
-      assertEquals(ramdisk, client.getInstanceServices().getRamdiskForInstanceInRegion(null, ebsInstance.getId()));
-   }
-
-   private void setKernelForInstanceInRegion() {
-      String oldKernel = client.getInstanceServices().getKernelForInstanceInRegion(null, ebsInstance.getId());
-      client.getInstanceServices().setKernelForInstanceInRegion(null, ebsInstance.getId(), oldKernel);
-      assertEquals(oldKernel, client.getInstanceServices().getKernelForInstanceInRegion(null, ebsInstance.getId()));
-   }
-
-   private void setInstanceTypeForInstanceInRegion() {
-      client.getInstanceServices()
-            .setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(), InstanceType.C1_MEDIUM);
-      assertEquals(InstanceType.C1_MEDIUM,
-            client.getInstanceServices().getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
-      client.getInstanceServices().setInstanceTypeForInstanceInRegion(null, ebsInstance.getId(), InstanceType.M1_SMALL);
-      assertEquals(InstanceType.M1_SMALL,
-            client.getInstanceServices().getInstanceTypeForInstanceInRegion(null, ebsInstance.getId()));
-   }
-
-   private void setBlockDeviceMappingForInstanceInRegion() {
-      String volumeId = ebsInstance.getEbsBlockDevices().get("/dev/sda1").getVolumeId();
-
-      Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
-      mapping.put("/dev/sda1", new BlockDevice(volumeId, false));
-      try {
-         client.getInstanceServices().setBlockDeviceMappingForInstanceInRegion(null, ebsInstance.getId(), mapping);
-
-         Map<String, BlockDevice> devices = client.getInstanceServices().getBlockDeviceMappingForInstanceInRegion(null,
-               ebsInstance.getId());
-         assertEquals(devices.size(), 1);
-         String deviceName = Iterables.getOnlyElement(devices.keySet());
-         BlockDevice device = Iterables.getOnlyElement(devices.values());
-
-         assertEquals(device.getVolumeId(), volumeId);
-         assertEquals(deviceName, "/dev/sda1");
-         assertEquals(device.isDeleteOnTermination(), false);
-
-         System.out.println("OK: setBlockDeviceMappingForInstanceInRegion");
-      } catch (Exception e) {
-         System.err.println("setBlockDeviceMappingForInstanceInRegion");
-
-         e.printStackTrace();
-      }
-   }
-
-   private void setInstanceInitiatedShutdownBehaviorForInstanceInRegion() {
-      try {
-
-         client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
-               ebsInstance.getId(), InstanceInitiatedShutdownBehavior.STOP);
-
-         assertEquals(InstanceInitiatedShutdownBehavior.STOP, client.getInstanceServices()
-               .getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null, ebsInstance.getId()));
-         client.getInstanceServices().setInstanceInitiatedShutdownBehaviorForInstanceInRegion(null,
-               ebsInstance.getId(), InstanceInitiatedShutdownBehavior.TERMINATE);
-
-         assertEquals(InstanceInitiatedShutdownBehavior.TERMINATE, client.getInstanceServices()
-               .getInstanceInitiatedShutdownBehaviorForInstanceInRegion(null, ebsInstance.getId()));
-         System.out.println("OK: setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
-      } catch (Exception e) {
-         System.err.println("setInstanceInitiatedShutdownBehaviorForInstanceInRegion");
-         e.printStackTrace();
-      }
-   }
-
-   /**
-    * this tests "personality" as the file looked up was sent during instance creation
-    * 
-    * @throws UnknownHostException
-    */
-   private void sshPing(RunningInstance newDetails) throws UnknownHostException {
-      try {
-         doCheckKey(newDetails);
-      } catch (SshException e) {// try twice in case there is a network timeout
-         try {
-            Thread.sleep(10 * 1000);
-         } catch (InterruptedException e1) {
-         }
-         doCheckKey(newDetails);
-      }
-   }
-
-   private void doCheckKey(RunningInstance newDetails) throws UnknownHostException {
-      doCheckKey(newDetails.getIpAddress());
-   }
-
-   private void doCheckKey(String address) {
-      SshClient ssh = sshFactory.create(HostAndPort.fromParts(address, 22),
-            LoginCredentials.builder().user("ubuntu").privateKey(keyPair.getKeyMaterial()).build());
-      try {
-         ssh.connect();
-         ExecResponse hello = ssh.exec("echo hello");
-         assertEquals(hello.getOutput().trim(), "hello");
-      } finally {
-         if (ssh != null)
-            ssh.disconnect();
-      }
-   }
-
-   private RunningInstance blockUntilWeCanSshIntoInstance(RunningInstance instance) throws UnknownHostException {
-      System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance.getId());
-      assert runningTester.apply(instance);
-
-      // search my identity for the instance I just created
-      Set<? extends Reservation<? extends RunningInstance>> reservations = client.getInstanceServices()
-            .describeInstancesInRegion(instance.getRegion(), instance.getId()); // last
-      // parameter
-      // (ids)
-      // narrows
-      // the
-      // search
-
-      instance = Iterables.getOnlyElement(Iterables.getOnlyElement(reservations));
-
-      System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), instance.getIpAddress());
-      assert socketTester.apply(HostAndPort.fromParts(instance.getIpAddress(), 22));
-      System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance.getDnsName());
-      sshPing(instance);
-      System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), instance.getId());
-      return instance;
-   }
-
-   @AfterTest
-   void cleanup() {
-      if (ebsInstance != null) {
-         try {
-            client.getInstanceServices().terminateInstancesInRegion(ebsInstance.getRegion(), ebsInstance.getId());
-            terminatedTester.apply(ebsInstance);
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (ebsImage != null) {
-         try {
-            client.getAMIServices().deregisterImageInRegion(ebsImage.getRegion(), ebsImage.getId());
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-
-      if (snapshot != null) {
-         try {
-            client.getElasticBlockStoreServices().deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId());
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (attachment != null) {
-         try {
-            client.getElasticBlockStoreServices().detachVolumeInRegion(volume.getRegion(), volume.getId(), true);
-            assert volumeTester.apply(volume);
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (instance != null) {
-         try {
-            client.getInstanceServices().terminateInstancesInRegion(instance.getRegion(), instance.getId());
-            terminatedTester.apply(instance);
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (volume != null) {
-         try {
-            client.getElasticBlockStoreServices().deleteVolumeInRegion(volume.getRegion(), volume.getId());
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (keyPair != null) {
-         try {
-            client.getKeyPairServices().deleteKeyPairInRegion(keyPair.getRegion(), keyPair.getKeyName());
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-      if (securityGroupName != null) {
-         try {
-            client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, securityGroupName);
-         } catch (Exception e) {
-            e.printStackTrace();
-         }
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java
deleted file mode 100644
index 17299b7..0000000
--- a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java
+++ /dev/null
@@ -1,75 +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.jclouds.ec2;
-
-import java.io.IOException;
-import java.util.concurrent.ExecutionException;
-
-import org.jclouds.ec2.services.BaseEC2AsyncClientTest;
-import org.jclouds.http.HttpRequest;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-/**
- * Tests behavior of {@code EC2AsyncClient}
- * 
- * @author Adrian Cole
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
-@Test(groups = "unit", testName = "EC2AsyncClientTest")
-public class EC2AsyncClientTest extends BaseEC2AsyncClientTest<EC2AsyncClient> {
-
-   private EC2AsyncClient asyncClient;
-   private EC2Client syncClient;
-
-   public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
-      assert syncClient.getAMIServices() != null;
-      assert syncClient.getAvailabilityZoneAndRegionServices() != null;
-      assert syncClient.getElasticBlockStoreServices() != null;
-      assert syncClient.getElasticIPAddressServices() != null;
-      assert syncClient.getInstanceServices() != null;
-      assert syncClient.getKeyPairServices() != null;
-      assert syncClient.getSecurityGroupServices() != null;
-      assert syncClient.getWindowsServices() != null;
-
-   }
-
-   public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
-      assert asyncClient.getAMIServices() != null;
-      assert asyncClient.getAvailabilityZoneAndRegionServices() != null;
-      assert asyncClient.getElasticBlockStoreServices() != null;
-      assert asyncClient.getElasticIPAddressServices() != null;
-      assert asyncClient.getInstanceServices() != null;
-      assert asyncClient.getKeyPairServices() != null;
-      assert asyncClient.getSecurityGroupServices() != null;
-      assert asyncClient.getWindowsServices() != null;
-   }
-
-   @BeforeClass
-   @Override
-   protected void setupFactory() throws IOException {
-      super.setupFactory();
-      asyncClient = injector.getInstance(EC2AsyncClient.class);
-      syncClient = injector.getInstance(EC2Client.class);
-   }
-
-   @Override
-   protected void checkFilters(HttpRequest request) {
-
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignatureTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignatureTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignatureTest.java
index e4290f6..5c92aec 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignatureTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/binders/BindS3UploadPolicyAndSignatureTest.java
@@ -20,8 +20,8 @@ import static org.testng.Assert.assertEquals;
 
 import java.io.IOException;
 
-import org.jclouds.ec2.services.BaseEC2AsyncClientTest;
-import org.jclouds.ec2.services.InstanceAsyncClient;
+import org.jclouds.ec2.features.BaseEC2ApiTest;
+import org.jclouds.ec2.features.InstanceApi;
 import org.jclouds.http.HttpRequest;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -33,7 +33,7 @@ import org.testng.annotations.Test;
  */
 // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
 @Test(groups = "unit", testName = "BindS3UploadPolicyAndSignatureTest")
-public class BindS3UploadPolicyAndSignatureTest extends BaseEC2AsyncClientTest<InstanceAsyncClient> {
+public class BindS3UploadPolicyAndSignatureTest extends BaseEC2ApiTest<InstanceApi> {
    private BindS3UploadPolicyAndSignature binder;
 
    @BeforeClass

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
index 6334c9a..c2753d72 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java
@@ -36,7 +36,7 @@ import org.jclouds.domain.Location;
 import org.jclouds.domain.LocationScope;
 import org.jclouds.domain.LoginCredentials;
 import org.jclouds.ec2.EC2ApiMetadata;
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.options.EC2TemplateOptions;
 import org.jclouds.ec2.domain.BlockDevice;
 import org.jclouds.ec2.domain.KeyPair;
@@ -46,10 +46,10 @@ import org.jclouds.ec2.domain.SecurityGroup;
 import org.jclouds.ec2.domain.Snapshot;
 import org.jclouds.ec2.domain.Volume;
 import org.jclouds.ec2.reference.EC2Constants;
-import org.jclouds.ec2.services.ElasticBlockStoreClient;
-import org.jclouds.ec2.services.InstanceClient;
-import org.jclouds.ec2.services.KeyPairClient;
-import org.jclouds.ec2.services.SecurityGroupClient;
+import org.jclouds.ec2.features.ElasticBlockStoreApi;
+import org.jclouds.ec2.features.InstanceApi;
+import org.jclouds.ec2.features.KeyPairApi;
+import org.jclouds.ec2.features.SecurityGroupApi;
 import org.jclouds.net.domain.IpProtocol;
 import org.jclouds.scriptbuilder.domain.Statements;
 import org.jclouds.sshj.config.SshjSshClientModule;
@@ -85,7 +85,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
 
    @Override
    protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
-      if (view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi().getTagApi().isPresent()) {
+      if (view.unwrapApi(EC2Api.class).getTagApi().isPresent()) {
          super.checkUserMetadataContains(node, userMetadata);
       } else {
          assertTrue(node.getUserMetadata().isEmpty(), "not expecting metadata when tag extension isn't present" + node);
@@ -103,14 +103,14 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
 
    @Test(enabled = true, dependsOnMethods = "testCompareSizes")
    public void testExtendedOptionsAndLogin() throws Exception {
-      SecurityGroupClient securityGroupClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi())
-               .getSecurityGroupServices();
+      SecurityGroupApi securityGroupClient = view.unwrapApi(EC2Api.class)
+               .getSecurityGroupApi().get();
 
-      KeyPairClient keyPairClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi())
-               .getKeyPairServices();
+      KeyPairApi keyPairClient = view.unwrapApi(EC2Api.class)
+               .getKeyPairApi().get();
 
-      InstanceClient instanceClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi())
-               .getInstanceServices();
+      InstanceApi instanceClient = view.unwrapApi(EC2Api.class)
+               .getInstanceApi().get();
 
       String group = this.group + "o";
 
@@ -203,9 +203,9 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
          assertTrue(socketTester.apply(socket), String.format("failed to open socket %s on node %s", socket, node));
 
          // check that there is an elastic ip correlating to it
-         EC2Client ec2 = EC2Client.class.cast(context.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi());
+         EC2Api ec2 = context.unwrapApi(EC2Api.class);
          Set<PublicIpInstanceIdPair> ipidpairs =
-               ec2.getElasticIPAddressServices().describeAddressesInRegion(region, publicIps.toArray(new String[0]));
+               ec2.getElasticIPAddressApi().get().describeAddressesInRegion(region, publicIps.toArray(new String[0]));
          assertEquals(ipidpairs.size(), 1, String.format("there should only be one address pair (%s)",
                Iterables.toString(ipidpairs)));
 
@@ -218,7 +218,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
 
          // check that the ip is deallocated
          Set<PublicIpInstanceIdPair> ipidcheck =
-                 ec2.getElasticIPAddressServices().describeAddressesInRegion(region, ipidpair.getPublicIp());
+                 ec2.getElasticIPAddressApi().get().describeAddressesInRegion(region, ipidpair.getPublicIp());
          assertTrue(Iterables.isEmpty(ipidcheck), String.format("there should be no address pairs (%s)",
                Iterables.toString(ipidcheck)));
       } finally {
@@ -246,11 +246,11 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
          throw new SkipException("Test cannot run without the parameter test." + provider
                + ".ebs-template; this property should be in the format defined in TemplateBuilderSpec");
       }
-      InstanceClient instanceClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi())
-               .getInstanceServices();
+      InstanceApi instanceClient = view.unwrapApi(EC2Api.class)
+               .getInstanceApi().get();
 
-      ElasticBlockStoreClient ebsClient = EC2Client.class.cast(view.unwrap(EC2ApiMetadata.CONTEXT_TOKEN).getApi())
-               .getElasticBlockStoreServices();
+      ElasticBlockStoreApi ebsClient = view.unwrapApi(EC2Api.class)
+               .getElasticBlockStoreApi().get();
 
       String group = this.group + "e";
       int volumeSize = 8;
@@ -317,14 +317,14 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
     * 
     * @throws NoSuchElementException If no instance with that id exists, or the instance is in a different region
     */
-   public static RunningInstance getInstance(InstanceClient instanceClient, String id) {
+   public static RunningInstance getInstance(InstanceApi instanceClient, String id) {
       RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
                .describeInstancesInRegion(null, id)));
       return instance;
    }
 
-   protected static void cleanupExtendedStuffInRegion(String region, SecurityGroupClient securityGroupClient,
-            KeyPairClient keyPairClient, String group) throws InterruptedException {
+   protected static void cleanupExtendedStuffInRegion(String region, SecurityGroupApi securityGroupClient,
+            KeyPairApi keyPairClient, String group) throws InterruptedException {
       try {
          for (SecurityGroup secgroup : securityGroupClient.describeSecurityGroupsInRegion(region))
             if (secgroup.getName().startsWith("jclouds#" + group) || secgroup.getName().equals(group)) {

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
index 8062033..349da8e 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderLiveTest.java
@@ -31,8 +31,8 @@ import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
 import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
 import org.jclouds.ec2.options.DescribeImagesOptions;
 import org.jclouds.ec2.options.DescribeRegionsOptions;
-import org.jclouds.ec2.services.AMIAsyncClient;
-import org.jclouds.ec2.services.AvailabilityZoneAndRegionAsyncClient;
+import org.jclouds.ec2.features.AMIApi;
+import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi;
 import org.jclouds.http.HttpCommand;
 import org.jclouds.http.internal.TrackingJavaUrlHttpCommandExecutorService;
 import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@@ -67,8 +67,8 @@ public abstract class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLive
 
          Collection<HttpCommand> filteredCommandsInvoked = Collections2.filter(commandsInvoked, new Predicate<HttpCommand>() {
             private final Collection<Method> ignored = ImmutableSet.of(
-                     AvailabilityZoneAndRegionAsyncClient.class.getMethod("describeRegions", DescribeRegionsOptions[].class),
-                     AvailabilityZoneAndRegionAsyncClient.class.getMethod("describeAvailabilityZonesInRegion", String.class, DescribeAvailabilityZonesOptions[].class));
+                     AvailabilityZoneAndRegionApi.class.getMethod("describeRegions", DescribeRegionsOptions[].class),
+                     AvailabilityZoneAndRegionApi.class.getMethod("describeAvailabilityZonesInRegion", String.class, DescribeAvailabilityZonesOptions[].class));
             @Override
             public boolean apply(HttpCommand input) {
                return !ignored.contains(getInvokerOfRequest(input));
@@ -76,7 +76,7 @@ public abstract class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLive
          });
          
          assert filteredCommandsInvoked.size() == 1 : commandsInvoked;
-         assertEquals(getInvokerOfRequestAtIndex(filteredCommandsInvoked, 0), AMIAsyncClient.class
+         assertEquals(getInvokerOfRequestAtIndex(filteredCommandsInvoked, 0), AMIApi.class
                   .getMethod("describeImagesInRegion", String.class, DescribeImagesOptions[].class));
          assertDescribeImagesOptionsEquals((DescribeImagesOptions[])getArgsForRequestAtIndex(filteredCommandsInvoked, 0).get(1), 
                   defaultImageProviderId);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java
index 789f8bc..ddee5e1 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java
@@ -25,11 +25,12 @@ import static org.testng.Assert.assertEquals;
 import java.net.UnknownHostException;
 
 import org.jclouds.ec2.EC2ApiMetadata;
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.domain.KeyPair;
-import org.jclouds.ec2.services.KeyPairClient;
+import org.jclouds.ec2.features.KeyPairApi;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 import com.google.inject.AbstractModule;
@@ -45,11 +46,11 @@ public class CreateUniqueKeyPairTest {
    
    @Test
    public void testApply() throws UnknownHostException {
-      final EC2Client client = createMock(EC2Client.class);
-      KeyPairClient keyClient = createMock(KeyPairClient.class);
+      final EC2Api client = createMock(EC2Api.class);
+      KeyPairApi keyClient = createMock(KeyPairApi.class);
       KeyPair pair = createMock(KeyPair.class);
 
-      expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
+      expect(client.getKeyPairApi()).andReturn((Optional) Optional.of(keyClient)).atLeastOnce();
 
       expect(keyClient.createKeyPairInRegion("region", "jclouds#group#1")).andReturn(pair);
 
@@ -63,7 +64,7 @@ public class CreateUniqueKeyPairTest {
             Names.bindProperties(binder(),new EC2ApiMetadata().getDefaultProperties());
             bind(new TypeLiteral<Supplier<String>>() {
             }).toInstance(Suppliers.ofInstance("1"));
-            bind(EC2Client.class).toInstance(client);
+            bind(EC2Api.class).toInstance(client);
          }
 
       }).getInstance(CreateUniqueKeyPair.class);
@@ -77,13 +78,13 @@ public class CreateUniqueKeyPairTest {
    @SuppressWarnings( { "unchecked" })
    @Test
    public void testApplyWithIllegalStateException() throws UnknownHostException {
-      final EC2Client client = createMock(EC2Client.class);
-      KeyPairClient keyClient = createMock(KeyPairClient.class);
+      final EC2Api client = createMock(EC2Api.class);
+      KeyPairApi keyClient = createMock(KeyPairApi.class);
       final Supplier<String> uniqueIdSupplier = createMock(Supplier.class);
 
       KeyPair pair = createMock(KeyPair.class);
 
-      expect(client.getKeyPairServices()).andReturn(keyClient).atLeastOnce();
+      expect(client.getKeyPairApi()).andReturn((Optional) Optional.of(keyClient)).atLeastOnce();
 
       expect(uniqueIdSupplier.get()).andReturn("1");
       expect(keyClient.createKeyPairInRegion("region", "jclouds#group#1")).andThrow(new IllegalStateException());
@@ -101,7 +102,7 @@ public class CreateUniqueKeyPairTest {
             Names.bindProperties(binder(),new EC2ApiMetadata().getDefaultProperties());
             bind(new TypeLiteral<Supplier<String>>() {
             }).toInstance(uniqueIdSupplier);
-            bind(EC2Client.class).toInstance(client);
+            bind(EC2Api.class).toInstance(client);
          }
 
       }).getInstance(CreateUniqueKeyPair.class);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/PresentInstancesTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/PresentInstancesTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/PresentInstancesTest.java
index cf5be25..d27b4e9 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/PresentInstancesTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/PresentInstancesTest.java
@@ -24,13 +24,14 @@ import static org.testng.Assert.assertEquals;
 
 import java.util.Set;
 
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.domain.RegionAndName;
 import org.jclouds.ec2.domain.Reservation;
 import org.jclouds.ec2.domain.RunningInstance;
-import org.jclouds.ec2.services.InstanceClient;
+import org.jclouds.ec2.features.InstanceApi;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -45,10 +46,10 @@ public class PresentInstancesTest {
    @Test
    public void testWhenInstancesPresentSingleCall() {
 
-      EC2Client client = createMock(EC2Client.class);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      EC2Api client = createMock(EC2Api.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
 
-      expect(client.getInstanceServices()).andReturn(instanceClient);
+      expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient));
 
       // avoid imatcher fail.  if you change this, be sure to check multiple jres
       expect(instanceClient.describeInstancesInRegion("us-east-1", "i-aaaa", "i-bbbb")).andReturn(

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java
index 9cd6b45..cc9790b 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/BaseEC2ComputeServiceContextExpectTest.java
@@ -19,14 +19,14 @@ package org.jclouds.ec2.compute.internal;
 import java.util.Properties;
 
 import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.ec2.internal.BaseEC2ClientExpectTest;
+import org.jclouds.ec2.internal.BaseEC2ApiExpectTest;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.http.HttpResponse;
 
 import com.google.common.base.Function;
 import com.google.inject.Module;
 
-public abstract class BaseEC2ComputeServiceContextExpectTest<T> extends BaseEC2ClientExpectTest<T> implements
+public abstract class BaseEC2ComputeServiceContextExpectTest<T> extends BaseEC2ApiExpectTest<T> implements
          Function<ComputeServiceContext, T> {
 
    @Override

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
index 9597e1a..1a2b9b3 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/CreateSecurityGroupIfNeededTest.java
@@ -31,7 +31,7 @@ import org.jclouds.ec2.compute.domain.RegionAndName;
 import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
 import org.jclouds.ec2.domain.SecurityGroup;
 import org.jclouds.ec2.domain.UserIdGroupPair;
-import org.jclouds.ec2.services.SecurityGroupClient;
+import org.jclouds.ec2.features.SecurityGroupApi;
 import org.jclouds.net.domain.IpProtocol;
 import org.testng.annotations.Test;
 
@@ -49,7 +49,7 @@ public class CreateSecurityGroupIfNeededTest {
    @Test
    public void testWhenPort22AndToItselfAuthorizesIngressTwice() throws ExecutionException {
 
-      SecurityGroupClient client = createMock(SecurityGroupClient.class);
+      SecurityGroupApi client = createMock(SecurityGroupApi.class);
       Predicate<RegionAndName> tester = Predicates.alwaysTrue();
 
       SecurityGroup group = createNiceMock(SecurityGroup.class);
@@ -76,7 +76,7 @@ public class CreateSecurityGroupIfNeededTest {
    @Test
    public void testIllegalStateExceptionCreatingGroupJustReturns() throws ExecutionException {
 
-      SecurityGroupClient client = createMock(SecurityGroupClient.class);
+      SecurityGroupApi client = createMock(SecurityGroupApi.class);
       Predicate<RegionAndName> tester = Predicates.alwaysTrue();
 
       client.createSecurityGroupInRegion("region", "group", "group");
@@ -95,7 +95,7 @@ public class CreateSecurityGroupIfNeededTest {
    @Test(expectedExceptions = RuntimeException.class)
    public void testWhenEventualConsistencyExpiresIllegalStateException() throws ExecutionException {
 
-      SecurityGroupClient client = createMock(SecurityGroupClient.class);
+      SecurityGroupApi client = createMock(SecurityGroupApi.class);
       Predicate<RegionAndName> tester = Predicates.alwaysFalse();
 
       client.createSecurityGroupInRegion("region", "group", "group");

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java
index 5389e86..9d3feff 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/LoadPublicIpForInstanceOrNullTest.java
@@ -22,12 +22,13 @@ import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 import static org.testng.Assert.assertEquals;
 
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.domain.RegionAndName;
 import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
-import org.jclouds.ec2.services.ElasticIPAddressClient;
+import org.jclouds.ec2.features.ElasticIPAddressApi;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -38,10 +39,10 @@ public class LoadPublicIpForInstanceOrNullTest {
 
    @Test
    public void testReturnsPublicIpOnMatch() throws Exception {
-      EC2Client client = createMock(EC2Client.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
+      EC2Api client = createMock(EC2Api.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
 
-      expect(client.getElasticIPAddressServices()).andReturn(ipClient).atLeastOnce();
+      expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce();
       expect(ipClient.describeAddressesInRegion("region")).andReturn(
                ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", "i-blah")))
                .atLeastOnce();
@@ -59,10 +60,10 @@ public class LoadPublicIpForInstanceOrNullTest {
 
    @Test
    public void testReturnsNullWhenNotFound() throws Exception {
-      EC2Client client = createMock(EC2Client.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
+      EC2Api client = createMock(EC2Api.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
 
-      expect(client.getElasticIPAddressServices()).andReturn(ipClient).atLeastOnce();
+      expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce();
 
       expect(ipClient.describeAddressesInRegion("region")).andReturn(ImmutableSet.<PublicIpInstanceIdPair> of())
                .atLeastOnce();
@@ -81,10 +82,10 @@ public class LoadPublicIpForInstanceOrNullTest {
 
    @Test
    public void testReturnsNullWhenNotAssigned() throws Exception {
-      EC2Client client = createMock(EC2Client.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
+      EC2Api client = createMock(EC2Api.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
 
-      expect(client.getElasticIPAddressServices()).andReturn(ipClient).atLeastOnce();
+      expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce();
 
       expect(ipClient.describeAddressesInRegion("region")).andReturn(
                ImmutableSet.<PublicIpInstanceIdPair> of(new PublicIpInstanceIdPair("region", "1.1.1.1", null)))

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/RegionAndIdToImageTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/RegionAndIdToImageTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/RegionAndIdToImageTest.java
index 64a76e9..5c1c2aa 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/RegionAndIdToImageTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/loaders/RegionAndIdToImageTest.java
@@ -29,13 +29,14 @@ import java.util.Set;
 import java.util.concurrent.ExecutionException;
 
 import org.jclouds.compute.domain.Image;
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.domain.RegionAndName;
 import org.jclouds.ec2.compute.functions.EC2ImageParser;
-import org.jclouds.ec2.services.AMIClient;
+import org.jclouds.ec2.features.AMIApi;
 import org.jclouds.rest.ResourceNotFoundException;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 
 /**
@@ -49,14 +50,14 @@ public class RegionAndIdToImageTest {
    public void testApply() throws ExecutionException {
 
       EC2ImageParser parser = createMock(EC2ImageParser.class);
-      EC2Client caller = createMock(EC2Client.class);
-      AMIClient client = createMock(AMIClient.class);
+      EC2Api caller = createMock(EC2Api.class);
+      AMIApi client = createMock(AMIApi.class);
 
       org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
       Image image = createNiceMock(Image.class);
       Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
 
-      expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
+      expect(caller.getAMIApi()).andReturn((Optional) Optional.of(client)).atLeastOnce();
       expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
       expect(parser.apply(ec2Image)).andReturn(image);
 
@@ -81,14 +82,14 @@ public class RegionAndIdToImageTest {
    public void testApplyNotFoundMakesExecutionException() throws ExecutionException {
 
       EC2ImageParser parser = createMock(EC2ImageParser.class);
-      EC2Client caller = createMock(EC2Client.class);
-      AMIClient client = createMock(AMIClient.class);
+      EC2Api caller = createMock(EC2Api.class);
+      AMIApi client = createMock(AMIApi.class);
 
       org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
       Image image = createNiceMock(Image.class);
       Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
 
-      expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
+      expect(caller.getAMIApi()).andReturn((Optional) Optional.of(client)).atLeastOnce();
       expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
       expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
 
@@ -113,14 +114,14 @@ public class RegionAndIdToImageTest {
    public void testApplyNoSuchElementExceptionMakesExecutionException() throws ExecutionException {
 
       EC2ImageParser parser = createMock(EC2ImageParser.class);
-      EC2Client caller = createMock(EC2Client.class);
-      AMIClient client = createMock(AMIClient.class);
+      EC2Api caller = createMock(EC2Api.class);
+      AMIApi client = createMock(AMIApi.class);
 
       org.jclouds.ec2.domain.Image ec2Image = createMock(org.jclouds.ec2.domain.Image.class);
       Image image = createNiceMock(Image.class);
       Set<? extends org.jclouds.ec2.domain.Image> images = ImmutableSet.<org.jclouds.ec2.domain.Image> of(ec2Image);
 
-      expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
+      expect(caller.getAMIApi()).andReturn((Optional) Optional.of(client)).atLeastOnce();
       expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn(Set.class.cast(images));
       expect(parser.apply(ec2Image)).andThrow(new NoSuchElementException());
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java
index 2a8bb45..b2ec12d 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSetTest.java
@@ -42,7 +42,7 @@ import org.jclouds.domain.Location;
 import org.jclouds.domain.LocationBuilder;
 import org.jclouds.domain.LocationScope;
 import org.jclouds.domain.LoginCredentials;
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.domain.RegionAndName;
 import org.jclouds.ec2.compute.functions.PresentInstances;
 import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata;
@@ -50,8 +50,8 @@ import org.jclouds.ec2.compute.options.EC2TemplateOptions;
 import org.jclouds.ec2.domain.Reservation;
 import org.jclouds.ec2.domain.RunningInstance;
 import org.jclouds.ec2.options.RunInstancesOptions;
-import org.jclouds.ec2.services.ElasticIPAddressClient;
-import org.jclouds.ec2.services.InstanceClient;
+import org.jclouds.ec2.features.ElasticIPAddressApi;
+import org.jclouds.ec2.features.InstanceApi;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -80,8 +80,8 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
       // setup mocks
       EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(nodeMetadata);
       InputParams input = new InputParams(location);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
       RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
       RunningInstance instance = createMock(RunningInstance.class);
       Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region,
@@ -93,11 +93,11 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
 
       // setup expectations
       expect(input.template.clone()).andReturn(input.template);
-      expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(strategy.client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(
             strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize
                   .execute(region, input.tag, input.template)).andReturn(ec2Options);
-      expect(strategy.client.getElasticIPAddressServices()).andReturn(ipClient).atLeastOnce();
+      expect(strategy.client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce();
 
       expect(input.template.getLocation()).andReturn(input.location).atLeastOnce();
       expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
@@ -191,7 +191,7 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
       // setup mocks
       EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(nodeMetadata);
       InputParams input = new InputParams(location);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
       RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class);
       RunningInstance instance = createMock(RunningInstance.class);
       Reservation<? extends RunningInstance> reservation = new Reservation<RunningInstance>(region,
@@ -200,7 +200,7 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
 
       // setup expectations
       expect(input.template.clone()).andReturn(input.template);
-      expect(strategy.client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(strategy.client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(
             strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize
                   .execute(region, input.tag, input.template)).andReturn(ec2Options);
@@ -307,7 +307,7 @@ public class EC2CreateNodesInGroupThenAddToSetTest {
 
    @SuppressWarnings("unchecked")
    private EC2CreateNodesInGroupThenAddToSet setupStrategy(final NodeMetadata node) {
-      EC2Client client = createMock(EC2Client.class);
+      EC2Api client = createMock(EC2Api.class);
       CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class);
       PresentInstances presentInstances = createMock(PresentInstances.class);
       RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java
index 8e892f2..6bc929c 100644
--- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategyTest.java
@@ -26,12 +26,13 @@ import java.util.concurrent.ExecutionException;
 
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
-import org.jclouds.ec2.EC2Client;
+import org.jclouds.ec2.EC2Api;
 import org.jclouds.ec2.compute.domain.RegionAndName;
-import org.jclouds.ec2.services.ElasticIPAddressClient;
-import org.jclouds.ec2.services.InstanceClient;
+import org.jclouds.ec2.features.ElasticIPAddressApi;
+import org.jclouds.ec2.features.InstanceApi;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Optional;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
 
@@ -44,14 +45,14 @@ public class EC2DestroyNodeStrategyTest {
    @SuppressWarnings("unchecked")
    @Test
    public void testDestroyNodeTerminatesInstanceAndReturnsRefreshedNode() throws Exception {
-      EC2Client client = createMock(EC2Client.class);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      EC2Api client = createMock(EC2Api.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
       GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class);
       LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class);
 
       NodeMetadata node = createMock(NodeMetadata.class);
 
-      expect(client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null);
       expect(getNode.getNode("region/i-blah")).andReturn(node);
 
@@ -74,23 +75,23 @@ public class EC2DestroyNodeStrategyTest {
    @Test
    public void testDestroyNodeDisassociatesAndReleasesIpThenTerminatesInstanceAndReturnsRefreshedNode()
             throws Exception {
-      EC2Client client = createMock(EC2Client.class);
+      EC2Api client = createMock(EC2Api.class);
       GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class);
       LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
 
       NodeMetadata node = createMock(NodeMetadata.class);
 
       expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andReturn("1.1.1.1");
 
-      expect(client.getElasticIPAddressServices()).andReturn(ipClient).atLeastOnce();
+      expect(client.getElasticIPAddressApi()).andReturn((Optional) Optional.of(ipClient)).atLeastOnce();
       ipClient.disassociateAddressInRegion("region", "1.1.1.1");
       ipClient.releaseAddressInRegion("region", "1.1.1.1");
       elasticIpCache.invalidate(new RegionAndName("region", "i-blah"));
 
 
-      expect(client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null);
       expect(getNode.getNode("region/i-blah")).andReturn(node);
 
@@ -117,17 +118,17 @@ public class EC2DestroyNodeStrategyTest {
    @Test
    public void testDestroyNodeSafeOnCacheMissThenTerminatesInstanceAndReturnsRefreshedNode()
             throws Exception {
-      EC2Client client = createMock(EC2Client.class);
+      EC2Api client = createMock(EC2Api.class);
       GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class);
       LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
 
       NodeMetadata node = createMock(NodeMetadata.class);
 
       expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andThrow(new CacheLoader.InvalidCacheLoadException(null));
 
-      expect(client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null);
       expect(getNode.getNode("region/i-blah")).andReturn(node);
 
@@ -154,17 +155,17 @@ public class EC2DestroyNodeStrategyTest {
    @Test
    public void testDestroyNodeSafeOnCacheExecutionExceptionThenTerminatesInstanceAndReturnsRefreshedNode()
             throws Exception {
-      EC2Client client = createMock(EC2Client.class);
+      EC2Api client = createMock(EC2Api.class);
       GetNodeMetadataStrategy getNode = createMock(GetNodeMetadataStrategy.class);
       LoadingCache<RegionAndName, String> elasticIpCache = createMock(LoadingCache.class);
-      ElasticIPAddressClient ipClient = createMock(ElasticIPAddressClient.class);
-      InstanceClient instanceClient = createMock(InstanceClient.class);
+      ElasticIPAddressApi ipClient = createMock(ElasticIPAddressApi.class);
+      InstanceApi instanceClient = createMock(InstanceApi.class);
 
       NodeMetadata node = createMock(NodeMetadata.class);
 
       expect(elasticIpCache.get(new RegionAndName("region", "i-blah"))).andThrow(new ExecutionException(null));
 
-      expect(client.getInstanceServices()).andReturn(instanceClient).atLeastOnce();
+      expect(client.getInstanceApi()).andReturn((Optional) Optional.of(instanceClient)).atLeastOnce();
       expect(instanceClient.terminateInstancesInRegion("region", "i-blah")).andReturn(null);
       expect(getNode.getNode("region/i-blah")).andReturn(node);
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java
new file mode 100644
index 0000000..0785228
--- /dev/null
+++ b/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2HttpApiModuleExpectTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.jclouds.ec2.config;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.jclouds.ec2.internal.BaseEC2ApiExpectTest;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.location.Region;
+import org.jclouds.location.Zone;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.location.functions.ZoneToEndpoint;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+
+/**
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "EC2HttpApiModuleExpectTest")
+public class EC2HttpApiModuleExpectTest extends BaseEC2ApiExpectTest<Injector> {
+   private Injector injector;
+
+   @BeforeClass
+   @Override
+   protected void setupDefaultRequests() {
+      super.setupDefaultRequests();
+      Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse> builder();
+      builder.put(describeRegionsRequest, describeRegionsResponse);
+      builder.putAll(describeAvailabilityZonesRequestResponse);
+
+      injector = requestsSendResponses(builder.build());
+   }
+
+   public void testLocationIdAndURIBindings() {
+
+      assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() {
+      }, Region.class)).get(), ImmutableSet.<String> of("sa-east-1", "ap-northeast-1", "eu-west-1", "us-east-1",
+            "us-west-1", "us-west-2", "ap-southeast-1"));
+
+      assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() {
+      }, Zone.class)).get(), ImmutableSet.<String> of("sa-east-1a", "sa-east-1b", "ap-northeast-1a", "ap-northeast-1b",
+            "eu-west-1a", "eu-west-1b", "eu-west-1c", "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d",
+            "us-east-1e", "us-west-1a", "us-west-1b", "us-west-1c", "us-west-2a", "us-west-2b", "us-west-2c",
+            "ap-southeast-1a", "ap-southeast-1b"));
+
+      Map<String, Supplier<URI>> regionToURISupplier = injector.getInstance(
+            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() {
+            }, Region.class)).get();
+
+      assertEquals(regionToURISupplier.get("sa-east-1").get(), URI.create("https://ec2.sa-east-1.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("ap-northeast-1").get(),
+            URI.create("https://ec2.ap-northeast-1.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("eu-west-1").get(), URI.create("https://ec2.eu-west-1.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("us-east-1").get(), URI.create("https://ec2.us-east-1.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("us-west-1").get(), URI.create("https://ec2.us-west-1.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("us-west-2").get(), URI.create("https://ec2.us-west-2.amazonaws.com"));
+      assertEquals(regionToURISupplier.get("ap-southeast-1").get(),
+            URI.create("https://ec2.ap-southeast-1.amazonaws.com"));
+
+      Map<String, Supplier<Set<String>>> regionToZoneIdSupplier = injector.getInstance(
+            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<Set<String>>>>>() {
+            }, Zone.class)).get();
+
+      assertEquals(regionToZoneIdSupplier.get("sa-east-1").get(), ImmutableSet.of("sa-east-1a", "sa-east-1b"));
+      assertEquals(regionToZoneIdSupplier.get("ap-northeast-1").get(),
+            ImmutableSet.of("ap-northeast-1a", "ap-northeast-1b"));
+      assertEquals(regionToZoneIdSupplier.get("eu-west-1").get(),
+            ImmutableSet.of("eu-west-1a", "eu-west-1b", "eu-west-1c"));
+      assertEquals(regionToZoneIdSupplier.get("us-east-1").get(),
+            ImmutableSet.of("us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e"));
+      assertEquals(regionToZoneIdSupplier.get("us-west-1").get(),
+            ImmutableSet.of("us-west-1a", "us-west-1b", "us-west-1c"));
+      assertEquals(regionToZoneIdSupplier.get("us-west-2").get(),
+            ImmutableSet.of("us-west-2a", "us-west-2b", "us-west-2c"));
+      assertEquals(regionToZoneIdSupplier.get("ap-southeast-1").get(),
+            ImmutableSet.of("ap-southeast-1a", "ap-southeast-1b"));
+
+      Map<String, Supplier<URI>> zoneToURISupplier = injector.getInstance(
+            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() {
+            }, Zone.class)).get();
+
+      assertEquals(zoneToURISupplier.get("sa-east-1a").get(), URI.create("https://ec2.sa-east-1.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("ap-northeast-1a").get(),
+            URI.create("https://ec2.ap-northeast-1.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("eu-west-1a").get(), URI.create("https://ec2.eu-west-1.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("us-east-1a").get(), URI.create("https://ec2.us-east-1.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("us-west-1a").get(), URI.create("https://ec2.us-west-1.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("us-west-2a").get(), URI.create("https://ec2.us-west-2.amazonaws.com"));
+
+      assertEquals(zoneToURISupplier.get("ap-southeast-1a").get(),
+            URI.create("https://ec2.ap-southeast-1.amazonaws.com"));
+
+   }
+
+   public void testZoneToEndpoint() {
+      assertEquals(injector.getInstance(ZoneToEndpoint.class).apply("us-west-2a"),
+            URI.create("https://ec2.us-west-2.amazonaws.com"));
+   }
+   
+   public void testRegionToEndpointOrProviderIfNull() {
+      assertEquals(injector.getInstance(RegionToEndpointOrProviderIfNull.class).apply("us-west-2"),
+            URI.create("https://ec2.us-west-2.amazonaws.com"));
+   }
+   
+   @Override
+   public Injector createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
+      return createInjector(fn, module, props);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/5f3b8d3f/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java
deleted file mode 100644
index a0c1975..0000000
--- a/apis/ec2/src/test/java/org/jclouds/ec2/config/EC2RestClientModuleExpectTest.java
+++ /dev/null
@@ -1,145 +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.jclouds.ec2.config;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.jclouds.ec2.internal.BaseEC2ClientExpectTest;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.jclouds.location.Region;
-import org.jclouds.location.Zone;
-import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
-import org.jclouds.location.functions.ZoneToEndpoint;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Module;
-import com.google.inject.TypeLiteral;
-
-/**
- * @author Adrian Cole
- */
-@Test(groups = "unit", testName = "EC2RestClientModuleExpectTest")
-public class EC2RestClientModuleExpectTest extends BaseEC2ClientExpectTest<Injector> {
-   private Injector injector;
-
-   @BeforeClass
-   @Override
-   protected void setupDefaultRequests() {
-      super.setupDefaultRequests();
-      Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse> builder();
-      builder.put(describeRegionsRequest, describeRegionsResponse);
-      builder.putAll(describeAvailabilityZonesRequestResponse);
-
-      injector = requestsSendResponses(builder.build());
-   }
-
-   public void testLocationIdAndURIBindings() {
-
-      assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() {
-      }, Region.class)).get(), ImmutableSet.<String> of("sa-east-1", "ap-northeast-1", "eu-west-1", "us-east-1",
-            "us-west-1", "us-west-2", "ap-southeast-1"));
-
-      assertEquals(injector.getInstance(Key.get(new TypeLiteral<Supplier<Set<String>>>() {
-      }, Zone.class)).get(), ImmutableSet.<String> of("sa-east-1a", "sa-east-1b", "ap-northeast-1a", "ap-northeast-1b",
-            "eu-west-1a", "eu-west-1b", "eu-west-1c", "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d",
-            "us-east-1e", "us-west-1a", "us-west-1b", "us-west-1c", "us-west-2a", "us-west-2b", "us-west-2c",
-            "ap-southeast-1a", "ap-southeast-1b"));
-
-      Map<String, Supplier<URI>> regionToURISupplier = injector.getInstance(
-            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() {
-            }, Region.class)).get();
-
-      assertEquals(regionToURISupplier.get("sa-east-1").get(), URI.create("https://ec2.sa-east-1.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("ap-northeast-1").get(),
-            URI.create("https://ec2.ap-northeast-1.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("eu-west-1").get(), URI.create("https://ec2.eu-west-1.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("us-east-1").get(), URI.create("https://ec2.us-east-1.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("us-west-1").get(), URI.create("https://ec2.us-west-1.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("us-west-2").get(), URI.create("https://ec2.us-west-2.amazonaws.com"));
-      assertEquals(regionToURISupplier.get("ap-southeast-1").get(),
-            URI.create("https://ec2.ap-southeast-1.amazonaws.com"));
-
-      Map<String, Supplier<Set<String>>> regionToZoneIdSupplier = injector.getInstance(
-            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<Set<String>>>>>() {
-            }, Zone.class)).get();
-
-      assertEquals(regionToZoneIdSupplier.get("sa-east-1").get(), ImmutableSet.of("sa-east-1a", "sa-east-1b"));
-      assertEquals(regionToZoneIdSupplier.get("ap-northeast-1").get(),
-            ImmutableSet.of("ap-northeast-1a", "ap-northeast-1b"));
-      assertEquals(regionToZoneIdSupplier.get("eu-west-1").get(),
-            ImmutableSet.of("eu-west-1a", "eu-west-1b", "eu-west-1c"));
-      assertEquals(regionToZoneIdSupplier.get("us-east-1").get(),
-            ImmutableSet.of("us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e"));
-      assertEquals(regionToZoneIdSupplier.get("us-west-1").get(),
-            ImmutableSet.of("us-west-1a", "us-west-1b", "us-west-1c"));
-      assertEquals(regionToZoneIdSupplier.get("us-west-2").get(),
-            ImmutableSet.of("us-west-2a", "us-west-2b", "us-west-2c"));
-      assertEquals(regionToZoneIdSupplier.get("ap-southeast-1").get(),
-            ImmutableSet.of("ap-southeast-1a", "ap-southeast-1b"));
-
-      Map<String, Supplier<URI>> zoneToURISupplier = injector.getInstance(
-            Key.get(new TypeLiteral<Supplier<Map<String, Supplier<URI>>>>() {
-            }, Zone.class)).get();
-
-      assertEquals(zoneToURISupplier.get("sa-east-1a").get(), URI.create("https://ec2.sa-east-1.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("ap-northeast-1a").get(),
-            URI.create("https://ec2.ap-northeast-1.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("eu-west-1a").get(), URI.create("https://ec2.eu-west-1.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("us-east-1a").get(), URI.create("https://ec2.us-east-1.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("us-west-1a").get(), URI.create("https://ec2.us-west-1.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("us-west-2a").get(), URI.create("https://ec2.us-west-2.amazonaws.com"));
-
-      assertEquals(zoneToURISupplier.get("ap-southeast-1a").get(),
-            URI.create("https://ec2.ap-southeast-1.amazonaws.com"));
-
-   }
-
-   public void testZoneToEndpoint() {
-      assertEquals(injector.getInstance(ZoneToEndpoint.class).apply("us-west-2a"),
-            URI.create("https://ec2.us-west-2.amazonaws.com"));
-   }
-   
-   public void testRegionToEndpointOrProviderIfNull() {
-      assertEquals(injector.getInstance(RegionToEndpointOrProviderIfNull.class).apply("us-west-2"),
-            URI.create("https://ec2.us-west-2.amazonaws.com"));
-   }
-   
-   @Override
-   public Injector createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
-      return createInjector(fn, module, props);
-   }
-
-}