Repository: jclouds
Updated Branches:
  refs/heads/master 35b71c572 -> 761329d27


JCLOUDS-972. Fix parsing of spot reqs, set sane default for validUntil.

Get the faultCode and faultMessage to actually be parsed (though I'm
not sure they're ever used), add statusCode, statusMessage and
statusUpdateTime, and have AWSEC2TemplateOptions default to a sane 30
minute lifetime for spot instance requests, so they don't get orphaned
forever if the price is too low etc.


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/761329d2
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/761329d2
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/761329d2

Branch: refs/heads/master
Commit: 761329d272017e378e919b97c7df985e1cfb76e2
Parents: 35b71c5
Author: Andrew Bayer <[email protected]>
Authored: Mon Jul 27 15:10:07 2015 +0200
Committer: Andrew Bayer <[email protected]>
Committed: Mon Jul 27 17:23:53 2015 +0200

----------------------------------------------------------------------
 .../aws/ec2/compute/AWSEC2TemplateOptions.java  |  7 +-
 .../aws/ec2/domain/SpotInstanceRequest.java     | 68 ++++++++++++++++++--
 .../aws/ec2/xml/SpotInstanceHandler.java        | 42 ++++++++++--
 .../aws/ec2/xml/SpotInstanceHandlerTest.java    | 10 +++
 .../test/resources/describe_spot_instance.xml   |  7 ++
 .../resources/request_spot_instances-ebs.xml    |  7 ++
 6 files changed, 131 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java
 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java
index 943a612..760a0aa 100644
--- 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java
+++ 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java
@@ -22,6 +22,8 @@ import static 
com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.base.Strings.emptyToNull;
 
+import java.util.Calendar;
+import java.util.Date;
 import java.util.Map;
 import java.util.Set;
 
@@ -217,7 +219,10 @@ public class AWSEC2TemplateOptions extends 
EC2TemplateOptions implements Cloneab
     * Options for starting spot instances
     */
    public AWSEC2TemplateOptions spotOptions(RequestSpotInstancesOptions 
spotOptions) {
-      this.spotOptions = spotOptions != null ? spotOptions : 
RequestSpotInstancesOptions.NONE;
+      Calendar cal = Calendar.getInstance();
+      cal.setTime(new Date());
+      cal.add(Calendar.MINUTE, 30);
+      this.spotOptions = spotOptions != null ? spotOptions : 
RequestSpotInstancesOptions.Builder.validUntil(cal.getTime());
       return this;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
index 58f5819..6ccf36f 100644
--- 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
+++ 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/SpotInstanceRequest.java
@@ -21,12 +21,11 @@ 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;
+import org.jclouds.javax.annotation.Nullable;
 
 public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
    public static Builder builder() {
@@ -51,6 +50,9 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
       private Type type;
       private Date validFrom;
       private Date validUntil;
+      private String statusCode;
+      private String statusMessage;
+      private Date statusUpdateTime;
       private Map<String, String> tags = Maps.newLinkedHashMap();
 
       public Builder clear() {
@@ -71,6 +73,9 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
          this.type = null;
          this.validFrom = null;
          this.validUntil = null;
+         this.statusCode = null;
+         this.statusMessage = null;
+         this.statusUpdateTime = null;
          tags = Maps.newLinkedHashMap();
          return this;
       }
@@ -170,10 +175,25 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
          return this;
       }
 
+      public Builder statusCode(String statusCode) {
+         this.statusCode = statusCode;
+         return this;
+      }
+
+      public Builder statusMessage(String statusMessage) {
+         this.statusMessage = statusMessage;
+         return this;
+      }
+
+      public Builder statusUpdateTime(Date statusUpdateTime) {
+         this.statusUpdateTime = statusUpdateTime;
+         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);
+                  rawState, type, validFrom, validUntil, statusCode, 
statusMessage, statusUpdateTime, tags);
       }
    }
 
@@ -236,12 +256,16 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
    private final Type type;
    private final Date validFrom;
    private final Date validUntil;
+   private final String statusCode;
+   private final String statusMessage;
+   private final Date statusUpdateTime;
    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) {
+            State state, String rawState, Type type, Date validFrom, Date 
validUntil, String statusCode,
+            String statusMessage, Date statusUpdateTime, Map<String, String> 
tags) {
       this.region = checkNotNull(region, "region");
       this.availabilityZoneGroup = availabilityZoneGroup;
       this.launchedAvailabilityZone = launchedAvailabilityZone;
@@ -259,6 +283,9 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
       this.type = checkNotNull(type, "type");
       this.validFrom = validFrom;
       this.validUntil = validUntil;
+      this.statusCode = statusCode;
+      this.statusMessage = statusMessage;
+      this.statusUpdateTime = statusUpdateTime;
       this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, 
"tags"));
    }
 
@@ -333,6 +360,18 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
       return validUntil;
    }
 
+   public String getStatusCode() {
+      return statusCode;
+   }
+
+   public String getStatusMessage() {
+      return statusMessage;
+   }
+
+   public Date getStatusUpdateTime() {
+      return statusUpdateTime;
+   }
+
    /**
     * tags that are present in the instance
     */
@@ -360,6 +399,9 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
       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 + ((statusCode == null) ? 0 : 
statusCode.hashCode());
+      result = prime * result + ((statusMessage == null) ? 0 : 
statusMessage.hashCode());
+      result = prime * result + ((statusUpdateTime == null) ? 0 : 
statusUpdateTime.hashCode());
       result = prime * result + ((tags == null) ? 0 : tags.hashCode());
       return result;
    }
@@ -444,6 +486,21 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
             return false;
       } else if (!validUntil.equals(other.validUntil))
          return false;
+      if (statusCode == null) {
+         if (other.statusCode != null)
+            return false;
+      } else if (!statusCode.equals(other.statusCode))
+         return false;
+      if (statusMessage == null) {
+         if (other.statusMessage != null)
+            return false;
+      } else if (!statusMessage.equals(other.statusMessage))
+         return false;
+      if (statusUpdateTime == null) {
+         if (other.statusUpdateTime != null)
+            return false;
+      } else if (!statusUpdateTime.equals(other.statusUpdateTime))
+         return false;
       if (tags == null) {
          if (other.tags != null)
             return false;
@@ -459,7 +516,8 @@ public class SpotInstanceRequest implements 
Comparable<SpotInstanceRequest> {
             + faultMessage + ", instanceId=" + instanceId + ", launchGroup=" + 
launchGroup + ", launchSpecification="
             + launchSpecification + ", productDescription=" + 
productDescription + ", id=" + id + ", spotPrice="
             + spotPrice + ", state=" + rawState + ", type=" + type + ", 
validFrom=" + validFrom + ", validUntil="
-            + validUntil + ", tags=" + tags + "]";
+            + validUntil + ", statusCode=" + statusCode + ", statusMessage=" + 
statusMessage + ", statusUpdateTime="
+            + statusUpdateTime + ", tags=" + tags + "]";
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/SpotInstanceHandler.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/SpotInstanceHandler.java
 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/SpotInstanceHandler.java
index 2c940ec..87ad370 100644
--- 
a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/SpotInstanceHandler.java
+++ 
b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/SpotInstanceHandler.java
@@ -40,6 +40,8 @@ public class SpotInstanceHandler extends 
ParseSax.HandlerForGeneratedRequestWith
    protected final DateCodec dateCodec;
    protected final Supplier<String> defaultRegion;
    protected final Builder builder;
+   protected boolean inFault;
+   protected boolean inStatus;
    protected boolean inLaunchSpecification;
    protected final LaunchSpecificationHandler launchSpecificationHandler;
    protected boolean inTagSet;
@@ -73,6 +75,10 @@ public class SpotInstanceHandler extends 
ParseSax.HandlerForGeneratedRequestWith
          inLaunchSpecification = true;
       } else if (equalsOrSuffix(qName, "tagSet")) {
          inTagSet = true;
+      } else if (equalsOrSuffix(qName, "fault")) {
+         inFault = true;
+      } else if (equalsOrSuffix(qName, "status")) {
+         inStatus = true;
       }
       if (inLaunchSpecification) {
           launchSpecificationHandler.startElement(uri, name, qName, attrs);
@@ -97,6 +103,14 @@ public class SpotInstanceHandler extends 
ParseSax.HandlerForGeneratedRequestWith
          launchSpecificationHandler.endElement(uri, name, qName);
       }
 
+      if (qName.equals("fault")) {
+         inFault = false;
+      }
+
+      if (qName.equals("status")) {
+         inStatus = false;
+      }
+
       if (qName.equals("spotInstanceRequestId")) {
          builder.id(currentOrNull(currentText));
       } else if (qName.equals("instanceId")) {
@@ -107,10 +121,6 @@ public class SpotInstanceHandler extends 
ParseSax.HandlerForGeneratedRequestWith
          builder.availabilityZoneGroup(currentOrNull(currentText));
       } else if (qName.equals("launchGroup")) {
          builder.launchGroup(currentOrNull(currentText));
-      } else if (qName.equals("code")) {
-         builder.faultCode(currentOrNull(currentText));
-      } else if (qName.equals("message")) {
-         builder.faultMessage(currentOrNull(currentText));
       } else if (qName.equals("spotPrice")) {
          String price = currentOrNull(currentText);
          if (price != null)
@@ -131,6 +141,30 @@ public class SpotInstanceHandler extends 
ParseSax.HandlerForGeneratedRequestWith
             builder.createTime(dateCodec.toDate(createTime));
       } else if (qName.equals("productDescription")) {
          builder.productDescription(currentOrNull(currentText));
+      } else if (inFault) {
+         if (qName.equals("code")) {
+            builder.faultCode(currentOrNull(currentText));
+         } else if (qName.equals("message")) {
+            builder.faultMessage(currentOrNull(currentText));
+         }
+      } else if (inStatus) {
+         if (qName.equals("code")) {
+            builder.statusCode(currentOrNull(currentText));
+         } else if (qName.equals("message")) {
+            builder.statusMessage(currentOrNull(currentText));
+         } else if (qName.equals("updateTime")) {
+            String updateTime = currentOrNull(currentText);
+            if (updateTime != null)
+               builder.statusUpdateTime(dateCodec.toDate(updateTime));
+         }
+      } else if (qName.equals("validFrom")) {
+         String validFrom = currentOrNull(currentText);
+         if (validFrom != null)
+            builder.validFrom(dateCodec.toDate(validFrom));
+      } else if (qName.equals("validUntil")) {
+         String validUntil = currentOrNull(currentText);
+         if (validUntil != null)
+            builder.validUntil(dateCodec.toDate(validUntil));
       }
       currentText.setLength(0);
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/SpotInstanceHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/SpotInstanceHandlerTest.java
 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/SpotInstanceHandlerTest.java
index ff5f230..757b9f4 100644
--- 
a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/SpotInstanceHandlerTest.java
+++ 
b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/SpotInstanceHandlerTest.java
@@ -77,6 +77,11 @@ public class SpotInstanceHandlerTest extends 
BaseEC2HandlerTest {
             .type(Type.ONE_TIME)
             .state(State.OPEN)
             .rawState("open")
+            .statusCode("pending-fulfillment")
+            .statusMessage("Pending fulfillment")
+            .statusUpdateTime(new 
SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
+            .validFrom(new 
SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
+            .validUntil(new 
SimpleDateFormatDateService().iso8601DateParse("2011-03-08T03:30:36.000Z"))
             .launchSpecification(
                   
LaunchSpecification.builder().imageId("ami-595a0a1c").securityGroupIdToName("sg-83e1c4ea",
 "default")
                         
.instanceType("m1.large").mapNewVolumeToDevice("/dev/sda1", 1, true)
@@ -110,6 +115,9 @@ public class SpotInstanceHandlerTest extends 
BaseEC2HandlerTest {
             .type(Type.ONE_TIME)
             .state(State.ACTIVE)
             .rawState("active")
+            .statusCode("fulfilled")
+            .statusMessage("Fulfilled")
+            .statusUpdateTime(new 
SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
             .launchedAvailabilityZone("us-east-1b")
             .launchSpecification(
                   LaunchSpecification.builder().imageId("ami-8e1fece7")
@@ -117,6 +125,8 @@ public class SpotInstanceHandlerTest extends 
BaseEC2HandlerTest {
                         
.instanceType("t1.micro").monitoringEnabled(false).keyName("jclouds#adriancole-ec2unssh")
                         .build())
             .createTime(new 
SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
+            .validFrom(new 
SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
+            .validUntil(new 
SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
             .productDescription("Linux/UNIX")
             .tag("Name", "ec2-o")
             .tag("Spot", "spot-value")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/test/resources/describe_spot_instance.xml
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/resources/describe_spot_instance.xml 
b/providers/aws-ec2/src/test/resources/describe_spot_instance.xml
index 964b246..c97f565 100644
--- a/providers/aws-ec2/src/test/resources/describe_spot_instance.xml
+++ b/providers/aws-ec2/src/test/resources/describe_spot_instance.xml
@@ -23,7 +23,14 @@
                 </monitoring>
             </launchSpecification>
             <instanceId>i-ef308e8e</instanceId>
+            <status>
+                <code>fulfilled</code>
+                <message>Fulfilled</message>
+                <updateTime>2011-07-29T05:27:39.000Z</updateTime>
+            </status>
             <createTime>2011-07-29T05:27:39.000Z</createTime>
+            <validFrom>2011-07-29T05:27:39.000Z</validFrom>
+            <validUntil>2011-07-29T05:27:39.000Z</validUntil>
             <productDescription>Linux/UNIX</productDescription>
             <tagSet>
                 <item>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/761329d2/providers/aws-ec2/src/test/resources/request_spot_instances-ebs.xml
----------------------------------------------------------------------
diff --git 
a/providers/aws-ec2/src/test/resources/request_spot_instances-ebs.xml 
b/providers/aws-ec2/src/test/resources/request_spot_instances-ebs.xml
index 7f64608..5569f67 100644
--- a/providers/aws-ec2/src/test/resources/request_spot_instances-ebs.xml
+++ b/providers/aws-ec2/src/test/resources/request_spot_instances-ebs.xml
@@ -45,7 +45,14 @@
                      <name>Webserver</name>
                 </iamInstanceProfile>
             </launchSpecification>
+            <status>
+                <code>pending-fulfillment</code>
+                <message>Pending fulfillment</message>
+                <updateTime>2011-03-08T03:30:36.000Z</updateTime>
+            </status>
             <createTime>2011-03-08T03:30:36.000Z</createTime>
+            <validFrom>2011-03-08T03:30:36.000Z</validFrom>
+            <validUntil>2011-03-08T03:30:36.000Z</validUntil>
             <productDescription>Linux/UNIX</productDescription>
         </item>
     </spotInstanceRequestSet>

Reply via email to