You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ra...@apache.org on 2014/11/25 16:25:26 UTC

[10/13] stratos git commit: Jclouds aws-ec2 provider 1.8.1 clone with custom changes

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
new file mode 100644
index 0000000..58f5819
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
@@ -0,0 +1,470 @@
+/*
+ * 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.aws.ec2.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Date;
+import java.util.Map;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static class Builder {
+      private String region;
+      private String availabilityZoneGroup;
+      private String launchedAvailabilityZone;
+      private Date createTime;
+      private String faultCode;
+      private String faultMessage;
+      private String instanceId;
+      private String launchGroup;
+      private LaunchSpecification launchSpecification;
+      private String productDescription;
+      private String id;
+      private float spotPrice;
+      private State state;
+      private String rawState;
+      private Type type;
+      private Date validFrom;
+      private Date validUntil;
+      private Map<String, String> tags = Maps.newLinkedHashMap();
+
+      public Builder clear() {
+         this.region = null;
+         this.availabilityZoneGroup = null;
+         this.launchedAvailabilityZone = null;
+         this.createTime = null;
+         this.faultCode = null;
+         this.faultMessage = null;
+         this.instanceId = null;
+         this.launchGroup = null;
+         this.launchSpecification = null;
+         this.productDescription = null;
+         this.id = null;
+         this.spotPrice = 0;
+         this.state = null;
+         this.rawState = null;
+         this.type = null;
+         this.validFrom = null;
+         this.validUntil = null;
+         tags = Maps.newLinkedHashMap();
+         return this;
+      }
+
+      public Builder region(String region) {
+         this.region = region;
+         return this;
+      }
+
+      public Builder tags(Map<String, String> tags) {
+         this.tags = ImmutableMap.copyOf(checkNotNull(tags, "tags"));
+         return this;
+      }
+
+      public Builder tag(String key, String value) {
+         if (key != null)
+            this.tags.put(key, Strings.nullToEmpty(value));
+         return this;
+      }
+      public Builder availabilityZoneGroup(String availabilityZoneGroup) {
+         this.availabilityZoneGroup = availabilityZoneGroup;
+         return this;
+      }
+
+      public Builder launchedAvailabilityZone(String launchedAvailabilityZone) {
+         this.launchedAvailabilityZone = launchedAvailabilityZone;
+         return this;
+      }
+
+      public Builder createTime(Date createTime) {
+         this.createTime = createTime;
+         return this;
+      }
+
+      public Builder faultCode(String faultCode) {
+         this.faultCode = faultCode;
+         return this;
+      }
+
+      public Builder faultMessage(String faultMessage) {
+         this.faultMessage = faultMessage;
+         return this;
+      }
+
+      public Builder instanceId(String instanceId) {
+         this.instanceId = instanceId;
+         return this;
+      }
+
+      public Builder launchGroup(String launchGroup) {
+         this.launchGroup = launchGroup;
+         return this;
+      }
+
+      public Builder launchSpecification(LaunchSpecification launchSpecification) {
+         this.launchSpecification = launchSpecification;
+         return this;
+      }
+
+      public Builder productDescription(String productDescription) {
+         this.productDescription = productDescription;
+         return this;
+      }
+
+      public Builder id(String id) {
+         this.id = id;
+         return this;
+      }
+
+      public Builder spotPrice(float spotPrice) {
+         this.spotPrice = spotPrice;
+         return this;
+      }
+
+      public Builder state(State state) {
+         this.state = state;
+         return this;
+      }
+      
+      public Builder rawState(String rawState) {
+         this.rawState = rawState;
+         return this;
+      }
+      
+      public Builder type(Type type) {
+         this.type = type;
+         return this;
+      }
+
+      public Builder validFrom(Date validFrom) {
+         this.validFrom = validFrom;
+         return this;
+      }
+
+      public Builder validUntil(Date validUntil) {
+         this.validUntil = validUntil;
+         return this;
+      }
+
+      public SpotInstanceRequest build() {
+         return new SpotInstanceRequest(region, availabilityZoneGroup, launchedAvailabilityZone, createTime, faultCode,
+                  faultMessage, instanceId, launchGroup, launchSpecification, productDescription, id, spotPrice, state,
+                  rawState, type, validFrom, validUntil, tags);
+      }
+   }
+
+   public enum Type {
+      ONE_TIME, PERSISTENT, UNRECOGNIZED;
+
+      public String value() {
+         return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
+      }
+
+      @Override
+      public String toString() {
+         return value();
+      }
+
+      public static Type fromValue(String type) {
+         try {
+            return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type")));
+         } catch (IllegalArgumentException e) {
+            return UNRECOGNIZED;
+         }
+      }
+   }
+
+   public enum State {
+      OPEN, ACTIVE, CANCELLED, CLOSED, UNRECOGNIZED;
+
+      public String value() {
+         return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
+      }
+
+      @Override
+      public String toString() {
+         return value();
+      }
+
+      public static State fromValue(String state) {
+         try {
+            return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "type")));
+         } catch (IllegalArgumentException e) {
+            return UNRECOGNIZED;
+         }
+      }
+   }
+
+   private final String region;
+   private final String availabilityZoneGroup;
+   private final String launchedAvailabilityZone;
+   private final Date createTime;
+   private final String faultCode;
+   private final String faultMessage;
+   private final String instanceId;
+   private final String launchGroup;
+   private final LaunchSpecification launchSpecification;
+   private final String productDescription;
+   private final String id;
+   private final float spotPrice;
+   private final State state;
+   private final String rawState;
+   private final Type type;
+   private final Date validFrom;
+   private final Date validUntil;
+   private final Map<String, String> tags;
+
+   public SpotInstanceRequest(String region, String availabilityZoneGroup, @Nullable String launchedAvailabilityZone,
+            Date createTime, String faultCode, String faultMessage, String instanceId, String launchGroup,
+            LaunchSpecification launchSpecification, String productDescription, String id, float spotPrice,
+            State state, String rawState, Type type, Date validFrom, Date validUntil, Map<String, String> tags) {
+      this.region = checkNotNull(region, "region");
+      this.availabilityZoneGroup = availabilityZoneGroup;
+      this.launchedAvailabilityZone = launchedAvailabilityZone;
+      this.createTime = createTime;
+      this.faultCode = faultCode;
+      this.faultMessage = faultMessage;
+      this.instanceId = instanceId;
+      this.launchGroup = launchGroup;
+      this.launchSpecification = launchSpecification;
+      this.productDescription = productDescription;
+      this.id = checkNotNull(id, "id");
+      this.spotPrice = spotPrice;
+      this.state = checkNotNull(state, "state");
+      this.rawState = checkNotNull(rawState, "rawState");
+      this.type = checkNotNull(type, "type");
+      this.validFrom = validFrom;
+      this.validUntil = validUntil;
+      this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags"));
+   }
+
+   /**
+    * @return spot instance requests are in a region
+    */
+   public String getRegion() {
+      return region;
+   }
+
+   public String getAvailabilityZoneGroup() {
+      return availabilityZoneGroup;
+   }
+
+   public String getLaunchedAvailabilityZone() {
+      return launchedAvailabilityZone;
+   }
+
+   public Date getCreateTime() {
+      return createTime;
+   }
+
+   public String getFaultCode() {
+      return faultCode;
+   }
+
+   public String getFaultMessage() {
+      return faultMessage;
+   }
+
+   public String getInstanceId() {
+      return instanceId;
+   }
+
+   public String getLaunchGroup() {
+      return launchGroup;
+   }
+
+   public LaunchSpecification getLaunchSpecification() {
+      return launchSpecification;
+   }
+
+   public String getProductDescription() {
+      return productDescription;
+   }
+
+   public String getId() {
+      return id;
+   }
+
+   public float getSpotPrice() {
+      return spotPrice;
+   }
+
+   public State getState() {
+      return state;
+   }
+   
+   public String getRawState() {
+      return rawState;
+   }
+   
+   public Type getType() {
+      return type;
+   }
+
+   public Date getValidFrom() {
+      return validFrom;
+   }
+
+   public Date getValidUntil() {
+      return validUntil;
+   }
+
+   /**
+    * tags that are present in the instance
+    */
+   public Map<String, String> getTags() {
+      return tags;
+   }
+   
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((availabilityZoneGroup == null) ? 0 : availabilityZoneGroup.hashCode());
+      result = prime * result + ((createTime == null) ? 0 : createTime.hashCode());
+      result = prime * result + ((faultCode == null) ? 0 : faultCode.hashCode());
+      result = prime * result + ((faultMessage == null) ? 0 : faultMessage.hashCode());
+      result = prime * result + ((id == null) ? 0 : id.hashCode());
+      result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
+      result = prime * result + ((launchGroup == null) ? 0 : launchGroup.hashCode());
+      result = prime * result + ((launchSpecification == null) ? 0 : launchSpecification.hashCode());
+      result = prime * result + ((launchedAvailabilityZone == null) ? 0 : launchedAvailabilityZone.hashCode());
+      result = prime * result + ((productDescription == null) ? 0 : productDescription.hashCode());
+      result = prime * result + ((region == null) ? 0 : region.hashCode());
+      result = prime * result + Float.floatToIntBits(spotPrice);
+      result = prime * result + ((state == null) ? 0 : state.hashCode());
+      result = prime * result + ((type == null) ? 0 : type.hashCode());
+      result = prime * result + ((validFrom == null) ? 0 : validFrom.hashCode());
+      result = prime * result + ((validUntil == null) ? 0 : validUntil.hashCode());
+      result = prime * result + ((tags == null) ? 0 : tags.hashCode());
+      return result;
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj)
+         return true;
+      if (obj == null)
+         return false;
+      if (getClass() != obj.getClass())
+         return false;
+      SpotInstanceRequest other = (SpotInstanceRequest) obj;
+      if (availabilityZoneGroup == null) {
+         if (other.availabilityZoneGroup != null)
+            return false;
+      } else if (!availabilityZoneGroup.equals(other.availabilityZoneGroup))
+         return false;
+      if (createTime == null) {
+         if (other.createTime != null)
+            return false;
+      } else if (!createTime.equals(other.createTime))
+         return false;
+      if (faultCode == null) {
+         if (other.faultCode != null)
+            return false;
+      } else if (!faultCode.equals(other.faultCode))
+         return false;
+      if (faultMessage == null) {
+         if (other.faultMessage != null)
+            return false;
+      } else if (!faultMessage.equals(other.faultMessage))
+         return false;
+      if (id == null) {
+         if (other.id != null)
+            return false;
+      } else if (!id.equals(other.id))
+         return false;
+      if (instanceId == null) {
+         if (other.instanceId != null)
+            return false;
+      } else if (!instanceId.equals(other.instanceId))
+         return false;
+      if (launchGroup == null) {
+         if (other.launchGroup != null)
+            return false;
+      } else if (!launchGroup.equals(other.launchGroup))
+         return false;
+      if (launchSpecification == null) {
+         if (other.launchSpecification != null)
+            return false;
+      } else if (!launchSpecification.equals(other.launchSpecification))
+         return false;
+      if (launchedAvailabilityZone == null) {
+         if (other.launchedAvailabilityZone != null)
+            return false;
+      } else if (!launchedAvailabilityZone.equals(other.launchedAvailabilityZone))
+         return false;
+      if (productDescription == null) {
+         if (other.productDescription != null)
+            return false;
+      } else if (!productDescription.equals(other.productDescription))
+         return false;
+      if (region == null) {
+         if (other.region != null)
+            return false;
+      } else if (!region.equals(other.region))
+         return false;
+      if (Float.floatToIntBits(spotPrice) != Float.floatToIntBits(other.spotPrice))
+         return false;
+      if (state != other.state)
+         return false;
+      if (type != other.type)
+         return false;
+      if (validFrom == null) {
+         if (other.validFrom != null)
+            return false;
+      } else if (!validFrom.equals(other.validFrom))
+         return false;
+      if (validUntil == null) {
+         if (other.validUntil != null)
+            return false;
+      } else if (!validUntil.equals(other.validUntil))
+         return false;
+      if (tags == null) {
+         if (other.tags != null)
+            return false;
+      } else if (!tags.equals(other.tags))
+         return false;
+      return true;
+   }
+
+   @Override
+   public String toString() {
+      return "[region=" + region + ", availabilityZoneGroup=" + availabilityZoneGroup + ", launchedAvailabilityZone="
+            + launchedAvailabilityZone + ", createTime=" + createTime + ", faultCode=" + faultCode + ", faultMessage="
+            + faultMessage + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup + ", launchSpecification="
+            + launchSpecification + ", productDescription=" + productDescription + ", id=" + id + ", spotPrice="
+            + spotPrice + ", state=" + rawState + ", type=" + type + ", validFrom=" + validFrom + ", validUntil="
+            + validUntil + ", tags=" + tags + "]";
+   }
+
+   @Override
+   public int compareTo(SpotInstanceRequest arg0) {
+      return createTime.compareTo(arg0.createTime);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSAMIApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSAMIApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSAMIApi.java
new file mode 100644
index 0000000..45f7f61
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSAMIApi.java
@@ -0,0 +1,124 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.aws.ec2.xml.ProductCodesHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindProductCodesToIndexedFormParams;
+import org.jclouds.ec2.features.AMIApi;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to AMI Services.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface AWSAMIApi extends AMIApi {
+   // TODO make AWSImage as it has product codes...
+
+   /**
+    * Returns the Product Codes of an image.
+    * 
+    * @param region
+    *           AMIs are tied to the Region where its files are located within Amazon S3.
+    * @param imageId
+    *           The ID of the AMI for which an attribute will be described
+    * @see #describeImages
+    * @see #modifyImageAttribute
+    * @see #resetImageAttribute
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImageAttribute.html"
+    *      />
+    * @see DescribeImagesOptions
+    */
+   @Named("DescribeImageAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" })
+   @XMLResponseParser(ProductCodesHandler.class)
+   Set<String> getProductCodesForImageInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("ImageId") String imageId);
+
+   /**
+    * Adds {@code productCode}s to an AMI.
+    * 
+    * @param region
+    *           AMIs are tied to the Region where its files are located within Amazon S3.
+    * @param productCodes
+    *           Product Codes
+    * @param imageId
+    *           The AMI ID.
+    * 
+    * @see #removeProductCodesFromImage
+    * @see #describeImageAttribute
+    * @see #resetImageAttribute
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyImageAttribute.html"
+    *      />
+    */
+   @Named("ModifyImageAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add",
+            "productCodes" })
+   void addProductCodesToImageInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable<String> productCodes,
+            @FormParam("ImageId") String imageId);
+
+   /**
+    * Removes {@code productCode}s from an AMI.
+    * 
+    * @param region
+    *           AMIs are tied to the Region where its files are located within Amazon S3.
+    * @param productCodes
+    *           Product Codes
+    * @param imageId
+    *           The AMI ID.
+    * 
+    * @see #addProductCodesToImage
+    * @see #describeImageAttribute
+    * @see #resetImageAttribute
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ModifyImageAttribute.html"
+    *      />
+    */
+   @Named("ModifyImageAttribute")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove",
+            "productCodes" })
+   void removeProductCodesFromImageInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable<String> productCodes,
+            @FormParam("ImageId") String imageId);
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSInstanceApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSInstanceApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSInstanceApi.java
new file mode 100644
index 0000000..186b473
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSInstanceApi.java
@@ -0,0 +1,92 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.aws.ec2.domain.AWSRunningInstance;
+import org.jclouds.aws.ec2.xml.AWSDescribeInstancesResponseHandler;
+import org.jclouds.aws.ec2.xml.AWSRunInstancesResponseHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
+import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
+import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam;
+import org.jclouds.ec2.domain.Reservation;
+import org.jclouds.ec2.features.InstanceApi;
+import org.jclouds.ec2.options.RunInstancesOptions;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides access to EC2 Instance Services via their REST API.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface AWSInstanceApi extends InstanceApi {
+
+   @Named("DescribeInstances")
+   @Override
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeInstances")
+   @XMLResponseParser(AWSDescribeInstancesResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<? extends Reservation<? extends AWSRunningInstance>> describeInstancesInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   @Named("DescribeInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeInstances")
+   @XMLResponseParser(AWSDescribeInstancesResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<? extends Reservation<? extends AWSRunningInstance>> describeInstancesInRegionWithFilter(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+           @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
+
+   @Named("RunInstances")
+   @Override
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RunInstances")
+   @XMLResponseParser(AWSRunInstancesResponseHandler.class)
+   Reservation<? extends AWSRunningInstance> runInstancesInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone,
+            @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount,
+            @FormParam("MaxCount") int maxCount, RunInstancesOptions... options);
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSKeyPairApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSKeyPairApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSKeyPairApi.java
new file mode 100644
index 0000000..0fb7bdf
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSKeyPairApi.java
@@ -0,0 +1,85 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.ec2.functions.EncodedRSAPublicKeyToBase64;
+import org.jclouds.ec2.features.KeyPairApi;
+import org.jclouds.ec2.xml.KeyPairResponseHandler;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.ParamParser;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface AWSKeyPairApi extends KeyPairApi {
+
+   /**
+    * Imports the public key from an RSA key pair that you created with a third-party tool. Compare
+    * this with CreateKeyPair, in which AWS creates the key pair and gives the keys to you (AWS
+    * keeps a copy of the public key). With ImportKeyPair, you create the key pair and give AWS just
+    * the public key. The private key is never transferred between you and AWS.
+    * 
+    * <p/>
+    * You can easily create an RSA key pair on Windows and Linux using the ssh-keygen command line
+    * tool (provided with the standard OpenSSH installation). Standard library support for RSA key
+    * pair creation is also available in Java, Ruby, Python, and many other programming languages.
+    * 
+    * <p/>
+    * <h4>Supported Formats</h4>
+    * <ul>
+    * <li>OpenSSH public key format (e.g., the format in ~/.ssh/authorized_keys)</li>
+    * <li>Base64 encoded DER format</li>
+    * <li>SSH public key file format as specified in RFC4716</li>
+    * </ul>
+    * DSA keys are not supported. Make sure your key generator is set up to create RSA keys.
+    * <p/>
+    * Supported lengths: 1024, 2048, and 4096.
+    * <p/>
+    * 
+    * @param region
+    *           region to import the key into
+    * @param keyName
+    *           A unique name for the key pair. Accepts alphanumeric characters, spaces, dashes, and
+    *           underscores.
+    * @param publicKeyMaterial
+    *           The public key
+    * @return imported key including fingerprint
+    */
+   @Named("ImportKeyPair")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "ImportKeyPair")
+   @XMLResponseParser(KeyPairResponseHandler.class)
+   KeyPair importKeyPairInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("KeyName") String keyName,
+         @FormParam("PublicKeyMaterial") @ParamParser(EncodedRSAPublicKeyToBase64.class) String publicKeyMaterial);
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.java
new file mode 100644
index 0000000..f4e06f6
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/AWSSecurityGroupApi.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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.aws.ec2.options.CreateSecurityGroupOptions;
+import org.jclouds.aws.ec2.xml.AWSEC2DescribeSecurityGroupsResponseHandler;
+import org.jclouds.aws.ec2.xml.CreateSecurityGroupResponseHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
+import org.jclouds.ec2.binders.BindGroupIdsToIndexedFormParams;
+import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
+import org.jclouds.ec2.binders.BindIpPermissionToIndexedFormParams;
+import org.jclouds.ec2.binders.BindIpPermissionsToIndexedFormParams;
+import org.jclouds.ec2.domain.SecurityGroup;
+import org.jclouds.ec2.features.SecurityGroupApi;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides access to EC2 SecurityGroup Services via their REST API.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+@Beta
+public interface AWSSecurityGroupApi extends SecurityGroupApi {
+
+   @Named("CreateSecurityGroup")
+   @POST
+   @Path("/")
+   @XMLResponseParser(CreateSecurityGroupResponseHandler.class)
+   @FormParams(keys = ACTION, values = "CreateSecurityGroup")
+   String createSecurityGroupInRegionAndReturnId(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("GroupName") String name, @FormParam("GroupDescription") String description,
+         CreateSecurityGroupOptions... options);
+
+   @Named("AuthorizeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
+   void authorizeSecurityGroupIngressInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("GroupId") String groupId, @BinderParam(BindIpPermissionToIndexedFormParams.class) IpPermission perm);
+
+   @Named("AuthorizeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
+   void authorizeSecurityGroupIngressInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("GroupId") String groupId,
+         @BinderParam(BindIpPermissionsToIndexedFormParams.class) Iterable<IpPermission> perms);
+
+   @Named("RevokeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
+   void revokeSecurityGroupIngressInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("GroupId") String groupId, @BinderParam(BindIpPermissionToIndexedFormParams.class) IpPermission perm);
+
+   @Named("RevokeSecurityGroupIngress")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
+   void revokeSecurityGroupIngressInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("GroupId") String groupId,
+         @BinderParam(BindIpPermissionsToIndexedFormParams.class) Iterable<IpPermission> perms);
+
+   @Named("DeleteSecurityGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeleteSecurityGroup")
+   @Fallback(VoidOnNotFoundOr404.class)
+   void deleteSecurityGroupInRegionById(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("GroupId") String name);
+
+   @Named("DescribeSecurityGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSecurityGroups")
+   @XMLResponseParser(AWSEC2DescribeSecurityGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<SecurityGroup> describeSecurityGroupsInRegionById(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindGroupIdsToIndexedFormParams.class) String... securityGroupNames);
+
+   @Named("DescribeSecurityGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSecurityGroups")
+   @XMLResponseParser(AWSEC2DescribeSecurityGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<SecurityGroup> describeSecurityGroupsInRegion(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+           @BinderParam(BindGroupNamesToIndexedFormParams.class) String... securityGroupNames);
+
+   @Named("DescribeSecurityGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSecurityGroups")
+   @XMLResponseParser(AWSEC2DescribeSecurityGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<SecurityGroup> describeSecurityGroupsInRegionWithFilter(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+           @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/MonitoringApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/MonitoringApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/MonitoringApi.java
new file mode 100644
index 0000000..dbe2dde
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/MonitoringApi.java
@@ -0,0 +1,95 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.aws.ec2.domain.MonitoringState;
+import org.jclouds.aws.ec2.xml.MonitoringStateHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to EC2 Monitoring Services via their REST API.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface MonitoringApi {
+
+   /**
+    * Enables monitoring for a running instance. For more information, refer to the Amazon
+    * CloudWatch Developer Guide.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance ID is tied to the
+    *           Region.
+    * @see InstanceApi#runInstances
+    * @see #unmonitorInstances
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-MonitorInstances.html"
+    *      />
+    */
+   @Named("MonitorInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "MonitorInstances")
+   @XMLResponseParser(MonitoringStateHandler.class)
+   Map<String, MonitoringState> monitorInstancesInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("InstanceId.0") String instanceId,
+            @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+
+   /**
+    * Disables monitoring for a running instance. For more information, refer to the Amazon
+    * CloudWatch Developer Guide.
+    * 
+    * @param region
+    *           Instances are tied to Availability Zones. However, the instance ID is tied to the
+    *           Region.
+    * 
+    * @see InstanceApi#runInstances
+    * @see #monitorInstances
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-UnmonitorInstances.html"
+    *      />
+    */
+   @Named("UnmonitorInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "UnmonitorInstances")
+   @XMLResponseParser(MonitoringStateHandler.class)
+   Map<String, MonitoringState> unmonitorInstancesInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("InstanceId.0") String instanceId,
+            @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/PlacementGroupApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/PlacementGroupApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/PlacementGroupApi.java
new file mode 100644
index 0000000..e165509
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/PlacementGroupApi.java
@@ -0,0 +1,160 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.aws.ec2.domain.PlacementGroup;
+import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
+import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides access to EC2 Placement Groups via their REST API.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface PlacementGroupApi {
+
+   /**
+    * Creates a placement group that you launch cluster compute instances into. You must give the
+    * group a name unique within the scope of your account.
+    * 
+    * @param region
+    *           Region to create the placement group in.
+    * @param name
+    *           The name of the placement group..
+    * @param strategy
+    *           The placement group strategy.
+    * @see #describePlacementGroupsInRegion
+    * @see #deletePlacementGroupInRegion
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreatePlacementGroup.html"
+    *      />
+    */
+   @Named("CreatePlacementGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CreatePlacementGroup")
+   void createPlacementGroupInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @FormParam("GroupName") String name, @FormParam("Strategy") String strategy);
+
+   /**
+    * like {@link #createPlacementGroupInRegion(String,String,String) except that the strategy is default: "cluster".
+    */
+   @Named("CreatePlacementGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = { ACTION, "Strategy" }, values = { "CreatePlacementGroup", "cluster" })
+   void createPlacementGroupInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("GroupName") String name);
+
+   /**
+    * Deletes a placement group from your account. You must terminate all instances in the placement group before deleting it.
+    * 
+    * @param region
+    *           Region to delete the placement from from
+    * @param name
+    *           Name of the security group to delete.
+    * 
+    * @see #describePlacementGroupsInRegion
+    * @see #createPlacementGroupInRegion
+    * 
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeletePlacementGroup.html"
+    *      />
+    */
+   @Named("DeletePlacementGroup")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DeletePlacementGroup")
+   @Fallback(VoidOnNotFoundOr404.class)
+   void deletePlacementGroupInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("GroupName") String name);
+
+   /**
+    * 
+    * Returns information about one or more placement groups in your account.
+    * 
+    * @param region
+    *           The bundleTask ID is tied to the Region.
+    * @param groupNames
+    *           The name of the placement group. You can specify more than one in the request, or
+    *           omit the parameter if you want information about all your placement groups. By
+    *           default, all placement groups are described
+    * 
+    * @see #deletePlacementGroupInRegion
+    * @see #createPlacementGroupInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribePlacementGroups.html"
+    *      />
+    */
+   @Named("DescribePlacementGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribePlacementGroups")
+   @XMLResponseParser(DescribePlacementGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<PlacementGroup> describePlacementGroupsInRegion(
+            @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+            @BinderParam(BindGroupNamesToIndexedFormParams.class) String... placementGroupIds);
+
+   /**
+    *
+    * Returns information about one or more placement groups in your account.
+    *
+    * @param region
+    *           The bundleTask ID is tied to the Region.
+    * @param filter
+    *           Multimap of filter key/values
+    *
+    * @see #deletePlacementGroupInRegion
+    * @see #createPlacementGroupInRegion
+    * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribePlacementGroups.html"
+    *      />
+    */
+   @Named("DescribePlacementGroups")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribePlacementGroups")
+   @XMLResponseParser(DescribePlacementGroupsResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<PlacementGroup> describePlacementGroupsInRegionWithFilter(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+           @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/SpotInstanceApi.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/SpotInstanceApi.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/SpotInstanceApi.java
new file mode 100644
index 0000000..694aab4
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/features/SpotInstanceApi.java
@@ -0,0 +1,245 @@
+/*
+ * 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.aws.ec2.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.aws.ec2.binders.BindLaunchSpecificationToFormParams;
+import org.jclouds.aws.ec2.binders.BindSpotInstanceRequestIdsToIndexedFormParams;
+import org.jclouds.aws.ec2.domain.LaunchSpecification;
+import org.jclouds.aws.ec2.domain.Spot;
+import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
+import org.jclouds.aws.ec2.options.DescribeSpotPriceHistoryOptions;
+import org.jclouds.aws.ec2.options.RequestSpotInstancesOptions;
+import org.jclouds.aws.ec2.xml.DescribeSpotPriceHistoryResponseHandler;
+import org.jclouds.aws.ec2.xml.SpotInstanceHandler;
+import org.jclouds.aws.ec2.xml.SpotInstancesHandler;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides access to EC2 Spot Instances via their REST API.
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@VirtualHost
+public interface SpotInstanceApi {
+
+   /**
+    * Describes Spot Instance requests. Spot Instances are instances that Amazon EC2 starts on your
+    * behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
+    * periodically sets the Spot Price based on available Spot Instance capacity and current spot
+    * instance requests. For conceptual information about Spot Instances, refer to the Amazon
+    * Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
+    * 
+    * @param region
+    *           Region where the spot instance service is running
+    * @param requestIds
+    *           Specifies the ID of the Spot Instance request.
+    * 
+    * @see #requestSpotInstancesInRegion
+    * @see #cancelSpotInstanceRequestsInRegion
+    * @see #describeSpotPriceHistoryInRegion
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html"
+    *      />
+    * @return TODO
+    */
+   @Named("DescribeSpotInstanceRequests")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSpotInstanceRequests")
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   @XMLResponseParser(SpotInstancesHandler.class)
+   Set<SpotInstanceRequest> describeSpotInstanceRequestsInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);
+
+   /**
+    * Describes Spot Instance requests. Spot Instances are instances that Amazon EC2 starts on your
+    * behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
+    * periodically sets the Spot Price based on available Spot Instance capacity and current spot
+    * instance requests. For conceptual information about Spot Instances, refer to the Amazon
+    * Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
+    *
+    * @param region
+    *           Region where the spot instance service is running
+    * @param filter
+    *           Mulitmap of filter key/values.
+    *
+    * @see #requestSpotInstancesInRegion
+    * @see #cancelSpotInstanceRequestsInRegion
+    * @see #describeSpotPriceHistoryInRegion
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html"
+    *      />
+    * @return TODO
+    */
+   @Named("DescribeSpotInstanceRequests")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSpotInstanceRequests")
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   @XMLResponseParser(SpotInstancesHandler.class)
+   Set<SpotInstanceRequest> describeSpotInstanceRequestsInRegionWithFilter(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+           @BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
+
+   /**
+    * request a single spot instance
+    * 
+    * @param region
+    *           Region where the spot instance service is running
+    * @param spotPrice
+    *           Specifies the maximum hourly price for any Spot Instance launched to fulfill the
+    *           request.
+    * @param imageId
+    *           The AMI ID.
+    * @param instanceType
+    *           The instance type (ex. m1.small)
+    * @return spot instance request
+    * @see #requestSpotInstancesInRegion
+    */
+   @Named("RequestSpotInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RequestSpotInstances")
+   @XMLResponseParser(SpotInstanceHandler.class)
+   SpotInstanceRequest requestSpotInstanceInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("SpotPrice") float spotPrice, @FormParam("LaunchSpecification.ImageId") String imageId,
+         @FormParam("LaunchSpecification.InstanceType") String instanceType);
+
+   /**
+    * Creates a Spot Instance request. Spot Instances are instances that Amazon EC2 starts on your
+    * behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
+    * periodically sets the Spot Price based on available Spot Instance capacity and current spot
+    * instance requests. For conceptual information about Spot Instances, refer to the Amazon
+    * Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
+    * 
+    * @param region
+    *           Region where the spot instance service is running
+    * @param spotPrice
+    *           Specifies the maximum hourly price for any Spot Instance launched to fulfill the
+    *           request.
+    * @param instanceCount
+    *           number of instances to request
+    * @param launchSpec
+    *           includes at least The AMI ID and instance type (ex. m1.small)
+    * @param options
+    *           options including expiration time or grouping
+    * 
+    * @see #describeSpotInstanceRequestsInRegion
+    * @see #cancelSpotInstanceRequestsInRegion
+    * @see #describeSpotPriceHistoryInRegion
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RequestSpotInstances.html"
+    *      />
+    * @return set of spot instance requests
+    */
+   @Named("RequestSpotInstances")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "RequestSpotInstances")
+   @XMLResponseParser(SpotInstancesHandler.class)
+   Set<SpotInstanceRequest> requestSpotInstancesInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @FormParam("SpotPrice") float spotPrice, @FormParam("InstanceCount") int instanceCount,
+         @BinderParam(BindLaunchSpecificationToFormParams.class) LaunchSpecification launchSpec,
+         RequestSpotInstancesOptions... options);
+
+   /**
+    * 
+    * Describes Spot Price history. Spot Instances are instances that Amazon EC2 starts on your
+    * behalf when the maximum price that you specify exceeds the current Spot Price. Amazon EC2
+    * periodically sets the Spot Price based on available Spot Instance capacity and current spot
+    * instance requests. For conceptual information about Spot Instances, refer to the Amazon
+    * Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
+    * 
+    * @param region
+    *           Region where the spot instance service is running
+    * @param options
+    *           options to control the list
+    * 
+    * @see #describeSpotInstanceRequestsInRegion
+    * @see #requestSpotInstancesInRegion
+    * @see #cancelSpotInstanceRequestsInRegion
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html"
+    *      />
+    * @return TODO
+    */
+   @Named("DescribeSpotPriceHistory")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "DescribeSpotPriceHistory")
+   @XMLResponseParser(DescribeSpotPriceHistoryResponseHandler.class)
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<Spot> describeSpotPriceHistoryInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         DescribeSpotPriceHistoryOptions... options);
+
+   /**
+    * Cancels one or more Spot Instance requests. Spot Instances are instances that Amazon EC2
+    * starts on your behalf when the maximum price that you specify exceeds the current Spot Price.
+    * Amazon EC2 periodically sets the Spot Price based on available Spot Instance capacity and
+    * current spot instance requests. For conceptual information about Spot Instances, refer to the
+    * Amazon Elastic Compute Cloud Developer Guide or Amazon Elastic Compute Cloud User Guide.
+    * 
+    * @param region
+    *           Region where the spot instance service is running
+    * @param requestIds
+    *           Specifies the ID of the Spot Instance request.
+    * 
+    * @see #describeSpotInstanceRequestsInRegion
+    * @see #requestSpotInstancesInRegion
+    * @see #describeSpotPriceHistoryInRegion
+    * @see <a href=
+    *      "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CancelSpotInstanceRequests.html"
+    *      />
+    * @return TODO
+    */
+   @Named("CancelSpotInstanceRequests")
+   @POST
+   @Path("/")
+   @FormParams(keys = ACTION, values = "CancelSpotInstanceRequests")
+   @Fallback(VoidOnNotFoundOr404.class)
+   void cancelSpotInstanceRequestsInRegion(
+         @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
+         @BinderParam(BindSpotInstanceRequestIdsToIndexedFormParams.class) String... requestIds);
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java
new file mode 100644
index 0000000..80d7054
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java
@@ -0,0 +1,77 @@
+/*
+ * 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.aws.ec2.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.AWSResponseException;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.ec2.domain.PlacementGroup;
+import org.jclouds.aws.ec2.domain.PlacementGroup.State;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Predicate;
+import com.google.common.cache.CacheLoader;
+
+@Singleton
+public class CreatePlacementGroupIfNeeded extends CacheLoader<RegionAndName, String> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   protected final AWSEC2Api ec2Api;
+   protected final Predicate<PlacementGroup> placementGroupAvailable;
+
+   @Inject
+   public CreatePlacementGroupIfNeeded(AWSEC2Api ec2Api,
+            @Named("AVAILABLE") Predicate<PlacementGroup> placementGroupAvailable) {
+      this.ec2Api = ec2Api;
+      this.placementGroupAvailable = placementGroupAvailable;
+   }
+
+   @Override
+   public String load(RegionAndName from) {
+      createPlacementGroupInRegion(from.getRegion(), from.getName());
+      return from.getName();
+   }
+
+   private void createPlacementGroupInRegion(String region, String name) {
+      checkNotNull(region, "region");
+      checkNotNull(name, "name");
+      logger.debug(">> creating placementGroup region(%s) name(%s)", region, name);
+      try {
+         ec2Api.getPlacementGroupApi().get().createPlacementGroupInRegion(region, name);
+         logger.debug("<< created placementGroup(%s)", name);
+         checkState(placementGroupAvailable.apply(new PlacementGroup(region, name, "cluster", State.PENDING)), String
+                  .format("placementGroup region(%s) name(%s) failed to become available", region, name));
+      } catch (AWSResponseException e) {
+         if (e.getError().getCode().equals("InvalidPlacementGroup.Duplicate")) {
+            logger.debug("<< reused placementGroup(%s)", name);
+         } else {
+            throw e;
+         }
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/ImportOrReturnExistingKeypair.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/ImportOrReturnExistingKeypair.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/ImportOrReturnExistingKeypair.java
new file mode 100644
index 0000000..9155b7a
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/ImportOrReturnExistingKeypair.java
@@ -0,0 +1,86 @@
+/*
+ * 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.aws.ec2.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.ssh.SshKeys.fingerprintPublicKey;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.ec2.domain.KeyPair;
+import org.jclouds.logging.Logger;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+@Singleton
+public class ImportOrReturnExistingKeypair implements Function<RegionNameAndPublicKeyMaterial, KeyPair> {
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+   protected final AWSEC2Api ec2Api;
+
+   @Inject
+   public ImportOrReturnExistingKeypair(AWSEC2Api ec2Api) {
+      this.ec2Api = ec2Api;
+   }
+
+   @Override
+   public KeyPair apply(RegionNameAndPublicKeyMaterial from) {
+      return importOrReturnExistingKeypair(from.getRegion(), from.getName(), from.getPublicKeyMaterial());
+   }
+
+   @VisibleForTesting
+   KeyPair importOrReturnExistingKeypair(String region, String group, String publicKeyMaterial) {
+      checkNotNull(region, "region");
+      checkNotNull(group, "group");
+      checkNotNull(publicKeyMaterial, "publicKeyMaterial");
+      logger.debug(">> importing keyPair region(%s) group(%s)", region, group);
+      KeyPair keyPair = null;
+      // loop for eventual consistency or race condition.
+      // as this command is idempotent, it should be ok
+      while (keyPair == null)
+         try {
+            keyPair = ec2Api.getKeyPairApi().get().importKeyPairInRegion(region, "jclouds#" + group,
+                     publicKeyMaterial);
+            keyPair = addFingerprintToKeyPair(publicKeyMaterial, keyPair);
+            logger.debug("<< imported keyPair(%s)", keyPair);
+         } catch (IllegalStateException e) {
+            keyPair = Iterables.getFirst(ec2Api.getKeyPairApi().get().describeKeyPairsInRegion(region,
+                     "jclouds#" + group), null);
+            if (keyPair != null) {
+               keyPair = addFingerprintToKeyPair(publicKeyMaterial, keyPair);
+               logger.debug("<< retrieved existing keyPair(%s)", keyPair);
+            }
+         }
+      return keyPair;
+   }
+
+   public KeyPair addFingerprintToKeyPair(String publicKeyMaterial, KeyPair keyPair) {
+      // add in the fingerprint as it makes correlating keys in ssh logs possible
+      keyPair = keyPair.toBuilder().fingerprint(fingerprintPublicKey(publicKeyMaterial)).build();
+      return keyPair;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/SpotInstanceRequestToAWSRunningInstance.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/SpotInstanceRequestToAWSRunningInstance.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/SpotInstanceRequestToAWSRunningInstance.java
new file mode 100644
index 0000000..7d9cf74
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/functions/SpotInstanceRequestToAWSRunningInstance.java
@@ -0,0 +1,60 @@
+/*
+ * 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.aws.ec2.functions;
+
+import org.jclouds.aws.ec2.domain.AWSRunningInstance;
+import org.jclouds.aws.ec2.domain.LaunchSpecification;
+import org.jclouds.aws.ec2.domain.MonitoringState;
+import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
+import org.jclouds.ec2.domain.Hypervisor;
+import org.jclouds.ec2.domain.InstanceState;
+
+import com.google.common.base.Function;
+
+public class SpotInstanceRequestToAWSRunningInstance implements Function<SpotInstanceRequest, AWSRunningInstance> {
+
+   @Override
+   public AWSRunningInstance apply(SpotInstanceRequest request) {
+      if (request == null)
+         return null;
+      if (request.getState() != SpotInstanceRequest.State.OPEN)
+         return null;
+      AWSRunningInstance.Builder builder = AWSRunningInstance.builder();
+      builder.spotInstanceRequestId(request.getId());
+      builder.instanceId(request.getId());
+      builder.instanceState(InstanceState.PENDING);
+      builder.rawState(request.getRawState());
+      builder.region(request.getRegion());
+      builder.tags(request.getTags());
+      LaunchSpecification spec = request.getLaunchSpecification();
+      builder.availabilityZone(spec.getAvailabilityZone());
+      // TODO convert
+      // builder.devices(spec.getBlockDeviceMappings());
+      builder.groupNames(spec.getSecurityGroupNames());
+      builder.imageId(spec.getImageId());
+      builder.instanceType(spec.getInstanceType());
+      builder.kernelId(spec.getKernelId());
+      builder.keyName(spec.getKeyName());
+      builder.ramdiskId(spec.getRamdiskId());
+      builder.monitoringState(Boolean.TRUE.equals(spec.isMonitoringEnabled()) ? MonitoringState.PENDING
+               : MonitoringState.DISABLED);
+      //TODO: determine the exact hypervisor
+      builder.hypervisor(Hypervisor.XEN);
+      return builder.build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/a5e842c0/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/options/AWSDescribeImagesOptions.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/options/AWSDescribeImagesOptions.java b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/options/AWSDescribeImagesOptions.java
new file mode 100644
index 0000000..2771c49
--- /dev/null
+++ b/dependencies/jclouds/provider/aws-ec2/1.8.1-stratos/src/main/java/org/jclouds/aws/ec2/options/AWSDescribeImagesOptions.java
@@ -0,0 +1,151 @@
+/*
+ * 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.aws.ec2.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.ec2.options.DescribeImagesOptions;
+
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+
+/**
+ * Extra options only available in Amazon's implementation
+ * 
+ * @see DescribeImagesOptions
+ */
+public class AWSDescribeImagesOptions extends DescribeImagesOptions {
+   public static final AWSDescribeImagesOptions NONE = new AWSDescribeImagesOptions();
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public AWSDescribeImagesOptions executableBy(String identityId) {
+      super.executableBy(identityId);
+      return this;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public AWSDescribeImagesOptions imageIds(String... imageIds) {
+      super.imageIds(imageIds);
+      return this;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public AWSDescribeImagesOptions imageIds(Iterable<String> imageIds) {
+      super.imageIds(imageIds);
+      return this;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public AWSDescribeImagesOptions ownedBy(String... owners) {
+      super.ownedBy(owners);
+      return this;
+   }
+
+   /**
+    * You can filter the results to return information only about images that match criteria you
+    * specify. For example, you could get information only about images that use a certain kernel.
+    * You can specify multiple values for a filter (e.g., the image uses either kernel aki-1a2b3c4d
+    * or kernel aki-9b8c7d6f). An image must match at least one of the specified values for it to be
+    * included in the results.
+    * <p/>
+    * You can specify multiple filters (e.g., the image uses a certain kernel, and uses an Amazon
+    * EBS volume as the root device). The result includes information for a particular image only if
+    * it matches all your filters. If there's no match, no special message is returned; the response
+    * is simply empty.
+    * <p/>
+    * You can use wildcards with the filter values: * matches zero or more characters, and ? matches
+    * exactly one character. You can escape special characters using a backslash before the
+    * character. For example, a value of \*amazon\?\\ searches for the literal string *amazon?\.
+    * 
+    */
+   public AWSDescribeImagesOptions filters(Multimap<String, String> filters) {
+      int i = 0;
+      for (Entry<String, Collection<String>> filter : checkNotNull(filters, "filters").asMap().entrySet()) {
+         String filterPrefix = String.format("Filter.%s.", ++i);
+         formParameters.put(filterPrefix + "Name", filter.getKey());
+         indexFormValuesWithPrefix(filterPrefix + "Value", filter.getValue());
+      }
+      return this;
+   }
+
+   /**
+    * @see #filters(Multimap)
+    */
+   public AWSDescribeImagesOptions filters(Map<String, String> filters) {
+      return filters(Multimaps.forMap(checkNotNull(filters, "filters")));
+   }
+
+   public static class Builder extends DescribeImagesOptions.Builder {
+
+      /**
+       * @see AWSDescribeImagesOptions#executableBy
+       */
+      public static AWSDescribeImagesOptions executableBy(String identityId) {
+         AWSDescribeImagesOptions options = new AWSDescribeImagesOptions();
+         return options.executableBy(identityId);
+      }
+
+      /**
+       * @see AWSDescribeImagesOptions#imageIds
+       */
+      public static AWSDescribeImagesOptions imageIds(String... imageIds) {
+         AWSDescribeImagesOptions options = new AWSDescribeImagesOptions();
+         return options.imageIds(imageIds);
+      }
+
+      /**
+       * @see AWSDescribeImagesOptions#filters(Multimap)
+       */
+      public static AWSDescribeImagesOptions filters(Multimap<String, String> filters) {
+         AWSDescribeImagesOptions options = new AWSDescribeImagesOptions();
+         return options.filters(filters);
+      }
+
+      /**
+       * @see AWSDescribeImagesOptions#filters(Map)
+       */
+      public static AWSDescribeImagesOptions filters(Map<String, String> filters) {
+         AWSDescribeImagesOptions options = new AWSDescribeImagesOptions();
+         return options.filters(filters);
+      }
+
+      /**
+       * @see AWSDescribeImagesOptions#ownedBy
+       */
+      public static AWSDescribeImagesOptions ownedBy(String... owners) {
+         AWSDescribeImagesOptions options = new AWSDescribeImagesOptions();
+         return options.ownedBy(owners);
+      }
+
+   }
+}