mirror of https://github.com/apache/jclouds.git
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.
This commit is contained in:
parent
8e5d378372
commit
6c94f3eb9e
|
@ -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.Preconditions.checkState;
|
||||||
import static com.google.common.base.Strings.emptyToNull;
|
import static com.google.common.base.Strings.emptyToNull;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -217,7 +219,10 @@ public class AWSEC2TemplateOptions extends EC2TemplateOptions implements Cloneab
|
||||||
* Options for starting spot instances
|
* Options for starting spot instances
|
||||||
*/
|
*/
|
||||||
public AWSEC2TemplateOptions spotOptions(RequestSpotInstancesOptions spotOptions) {
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import com.google.common.base.CaseFormat;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
@ -51,6 +50,9 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
private Type type;
|
private Type type;
|
||||||
private Date validFrom;
|
private Date validFrom;
|
||||||
private Date validUntil;
|
private Date validUntil;
|
||||||
|
private String statusCode;
|
||||||
|
private String statusMessage;
|
||||||
|
private Date statusUpdateTime;
|
||||||
private Map<String, String> tags = Maps.newLinkedHashMap();
|
private Map<String, String> tags = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
public Builder clear() {
|
public Builder clear() {
|
||||||
|
@ -71,6 +73,9 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
this.type = null;
|
this.type = null;
|
||||||
this.validFrom = null;
|
this.validFrom = null;
|
||||||
this.validUntil = null;
|
this.validUntil = null;
|
||||||
|
this.statusCode = null;
|
||||||
|
this.statusMessage = null;
|
||||||
|
this.statusUpdateTime = null;
|
||||||
tags = Maps.newLinkedHashMap();
|
tags = Maps.newLinkedHashMap();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -170,10 +175,25 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
return this;
|
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() {
|
public SpotInstanceRequest build() {
|
||||||
return new SpotInstanceRequest(region, availabilityZoneGroup, launchedAvailabilityZone, createTime, faultCode,
|
return new SpotInstanceRequest(region, availabilityZoneGroup, launchedAvailabilityZone, createTime, faultCode,
|
||||||
faultMessage, instanceId, launchGroup, launchSpecification, productDescription, id, spotPrice, state,
|
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 Type type;
|
||||||
private final Date validFrom;
|
private final Date validFrom;
|
||||||
private final Date validUntil;
|
private final Date validUntil;
|
||||||
|
private final String statusCode;
|
||||||
|
private final String statusMessage;
|
||||||
|
private final Date statusUpdateTime;
|
||||||
private final Map<String, String> tags;
|
private final Map<String, String> tags;
|
||||||
|
|
||||||
public SpotInstanceRequest(String region, String availabilityZoneGroup, @Nullable String launchedAvailabilityZone,
|
public SpotInstanceRequest(String region, String availabilityZoneGroup, @Nullable String launchedAvailabilityZone,
|
||||||
Date createTime, String faultCode, String faultMessage, String instanceId, String launchGroup,
|
Date createTime, String faultCode, String faultMessage, String instanceId, String launchGroup,
|
||||||
LaunchSpecification launchSpecification, String productDescription, String id, float spotPrice,
|
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.region = checkNotNull(region, "region");
|
||||||
this.availabilityZoneGroup = availabilityZoneGroup;
|
this.availabilityZoneGroup = availabilityZoneGroup;
|
||||||
this.launchedAvailabilityZone = launchedAvailabilityZone;
|
this.launchedAvailabilityZone = launchedAvailabilityZone;
|
||||||
|
@ -259,6 +283,9 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
this.type = checkNotNull(type, "type");
|
this.type = checkNotNull(type, "type");
|
||||||
this.validFrom = validFrom;
|
this.validFrom = validFrom;
|
||||||
this.validUntil = validUntil;
|
this.validUntil = validUntil;
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
this.statusMessage = statusMessage;
|
||||||
|
this.statusUpdateTime = statusUpdateTime;
|
||||||
this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags"));
|
this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +360,18 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
return validUntil;
|
return validUntil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatusMessage() {
|
||||||
|
return statusMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getStatusUpdateTime() {
|
||||||
|
return statusUpdateTime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tags that are present in the instance
|
* 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 + ((type == null) ? 0 : type.hashCode());
|
||||||
result = prime * result + ((validFrom == null) ? 0 : validFrom.hashCode());
|
result = prime * result + ((validFrom == null) ? 0 : validFrom.hashCode());
|
||||||
result = prime * result + ((validUntil == null) ? 0 : validUntil.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());
|
result = prime * result + ((tags == null) ? 0 : tags.hashCode());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +486,21 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
return false;
|
return false;
|
||||||
} else if (!validUntil.equals(other.validUntil))
|
} else if (!validUntil.equals(other.validUntil))
|
||||||
return false;
|
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 (tags == null) {
|
||||||
if (other.tags != null)
|
if (other.tags != null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -459,7 +516,8 @@ public class SpotInstanceRequest implements Comparable<SpotInstanceRequest> {
|
||||||
+ faultMessage + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup + ", launchSpecification="
|
+ faultMessage + ", instanceId=" + instanceId + ", launchGroup=" + launchGroup + ", launchSpecification="
|
||||||
+ launchSpecification + ", productDescription=" + productDescription + ", id=" + id + ", spotPrice="
|
+ launchSpecification + ", productDescription=" + productDescription + ", id=" + id + ", spotPrice="
|
||||||
+ spotPrice + ", state=" + rawState + ", type=" + type + ", validFrom=" + validFrom + ", validUntil="
|
+ spotPrice + ", state=" + rawState + ", type=" + type + ", validFrom=" + validFrom + ", validUntil="
|
||||||
+ validUntil + ", tags=" + tags + "]";
|
+ validUntil + ", statusCode=" + statusCode + ", statusMessage=" + statusMessage + ", statusUpdateTime="
|
||||||
|
+ statusUpdateTime + ", tags=" + tags + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -40,6 +40,8 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
||||||
protected final DateCodec dateCodec;
|
protected final DateCodec dateCodec;
|
||||||
protected final Supplier<String> defaultRegion;
|
protected final Supplier<String> defaultRegion;
|
||||||
protected final Builder builder;
|
protected final Builder builder;
|
||||||
|
protected boolean inFault;
|
||||||
|
protected boolean inStatus;
|
||||||
protected boolean inLaunchSpecification;
|
protected boolean inLaunchSpecification;
|
||||||
protected final LaunchSpecificationHandler launchSpecificationHandler;
|
protected final LaunchSpecificationHandler launchSpecificationHandler;
|
||||||
protected boolean inTagSet;
|
protected boolean inTagSet;
|
||||||
|
@ -73,6 +75,10 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
||||||
inLaunchSpecification = true;
|
inLaunchSpecification = true;
|
||||||
} else if (equalsOrSuffix(qName, "tagSet")) {
|
} else if (equalsOrSuffix(qName, "tagSet")) {
|
||||||
inTagSet = true;
|
inTagSet = true;
|
||||||
|
} else if (equalsOrSuffix(qName, "fault")) {
|
||||||
|
inFault = true;
|
||||||
|
} else if (equalsOrSuffix(qName, "status")) {
|
||||||
|
inStatus = true;
|
||||||
}
|
}
|
||||||
if (inLaunchSpecification) {
|
if (inLaunchSpecification) {
|
||||||
launchSpecificationHandler.startElement(uri, name, qName, attrs);
|
launchSpecificationHandler.startElement(uri, name, qName, attrs);
|
||||||
|
@ -97,6 +103,14 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
||||||
launchSpecificationHandler.endElement(uri, name, qName);
|
launchSpecificationHandler.endElement(uri, name, qName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qName.equals("fault")) {
|
||||||
|
inFault = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qName.equals("status")) {
|
||||||
|
inStatus = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (qName.equals("spotInstanceRequestId")) {
|
if (qName.equals("spotInstanceRequestId")) {
|
||||||
builder.id(currentOrNull(currentText));
|
builder.id(currentOrNull(currentText));
|
||||||
} else if (qName.equals("instanceId")) {
|
} else if (qName.equals("instanceId")) {
|
||||||
|
@ -107,10 +121,6 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
||||||
builder.availabilityZoneGroup(currentOrNull(currentText));
|
builder.availabilityZoneGroup(currentOrNull(currentText));
|
||||||
} else if (qName.equals("launchGroup")) {
|
} else if (qName.equals("launchGroup")) {
|
||||||
builder.launchGroup(currentOrNull(currentText));
|
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")) {
|
} else if (qName.equals("spotPrice")) {
|
||||||
String price = currentOrNull(currentText);
|
String price = currentOrNull(currentText);
|
||||||
if (price != null)
|
if (price != null)
|
||||||
|
@ -131,6 +141,30 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
|
||||||
builder.createTime(dateCodec.toDate(createTime));
|
builder.createTime(dateCodec.toDate(createTime));
|
||||||
} else if (qName.equals("productDescription")) {
|
} else if (qName.equals("productDescription")) {
|
||||||
builder.productDescription(currentOrNull(currentText));
|
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);
|
currentText.setLength(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,11 @@ public class SpotInstanceHandlerTest extends BaseEC2HandlerTest {
|
||||||
.type(Type.ONE_TIME)
|
.type(Type.ONE_TIME)
|
||||||
.state(State.OPEN)
|
.state(State.OPEN)
|
||||||
.rawState("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(
|
||||||
LaunchSpecification.builder().imageId("ami-595a0a1c").securityGroupIdToName("sg-83e1c4ea", "default")
|
LaunchSpecification.builder().imageId("ami-595a0a1c").securityGroupIdToName("sg-83e1c4ea", "default")
|
||||||
.instanceType("m1.large").mapNewVolumeToDevice("/dev/sda1", 1, true)
|
.instanceType("m1.large").mapNewVolumeToDevice("/dev/sda1", 1, true)
|
||||||
|
@ -110,6 +115,9 @@ public class SpotInstanceHandlerTest extends BaseEC2HandlerTest {
|
||||||
.type(Type.ONE_TIME)
|
.type(Type.ONE_TIME)
|
||||||
.state(State.ACTIVE)
|
.state(State.ACTIVE)
|
||||||
.rawState("active")
|
.rawState("active")
|
||||||
|
.statusCode("fulfilled")
|
||||||
|
.statusMessage("Fulfilled")
|
||||||
|
.statusUpdateTime(new SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
|
||||||
.launchedAvailabilityZone("us-east-1b")
|
.launchedAvailabilityZone("us-east-1b")
|
||||||
.launchSpecification(
|
.launchSpecification(
|
||||||
LaunchSpecification.builder().imageId("ami-8e1fece7")
|
LaunchSpecification.builder().imageId("ami-8e1fece7")
|
||||||
|
@ -117,6 +125,8 @@ public class SpotInstanceHandlerTest extends BaseEC2HandlerTest {
|
||||||
.instanceType("t1.micro").monitoringEnabled(false).keyName("jclouds#adriancole-ec2unssh")
|
.instanceType("t1.micro").monitoringEnabled(false).keyName("jclouds#adriancole-ec2unssh")
|
||||||
.build())
|
.build())
|
||||||
.createTime(new SimpleDateFormatDateService().iso8601DateParse("2011-07-29T05:27:39.000Z"))
|
.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")
|
.productDescription("Linux/UNIX")
|
||||||
.tag("Name", "ec2-o")
|
.tag("Name", "ec2-o")
|
||||||
.tag("Spot", "spot-value")
|
.tag("Spot", "spot-value")
|
||||||
|
|
|
@ -23,7 +23,14 @@
|
||||||
</monitoring>
|
</monitoring>
|
||||||
</launchSpecification>
|
</launchSpecification>
|
||||||
<instanceId>i-ef308e8e</instanceId>
|
<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>
|
<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>
|
<productDescription>Linux/UNIX</productDescription>
|
||||||
<tagSet>
|
<tagSet>
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -45,7 +45,14 @@
|
||||||
<name>Webserver</name>
|
<name>Webserver</name>
|
||||||
</iamInstanceProfile>
|
</iamInstanceProfile>
|
||||||
</launchSpecification>
|
</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>
|
<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>
|
<productDescription>Linux/UNIX</productDescription>
|
||||||
</item>
|
</item>
|
||||||
</spotInstanceRequestSet>
|
</spotInstanceRequestSet>
|
||||||
|
|
Loading…
Reference in New Issue