Merge remote-tracking branch 'upstream/master' into generic-tempurl

This commit is contained in:
Andrei Savu 2012-09-16 23:11:30 +03:00
commit 64a9888622
27 changed files with 378 additions and 256 deletions

View File

@ -93,8 +93,10 @@ public class MetricDataBinder implements org.jclouds.rest.Binder {
formParameters.put("MetricData.member." + metricDatumIndex + ".Unit",
String.valueOf(metricDatum.getUnit()));
if (metricDatum.getValue().isPresent()) {
formParameters.put("MetricData.member." + metricDatumIndex + ".Value",
String.valueOf(metricDatum.getValue()));
String.valueOf(metricDatum.getValue().get()));
}
metricDatumIndex++;
}

View File

@ -25,13 +25,15 @@ import java.util.Date;
import java.util.Set;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html" />
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html"
* />
*
* @author Jeremy Whitlock
*/
@ -42,17 +44,17 @@ public class MetricDatum {
private final Optional<StatisticValues> statisticValues;
private final Optional<Date> timestamp;
private final Unit unit;
private final double value;
private final Optional<Double> value;
/**
* Private constructor to enforce using {@link Builder}.
*/
protected MetricDatum(Set<Dimension> dimensions, String metricName, StatisticValues statisticValues, Date timestamp,
Unit unit, double value) {
this.dimensions = ImmutableSet.<Dimension>copyOf(checkNotNull(dimensions, "dimensions"));
protected MetricDatum(Iterable<Dimension> dimensions, String metricName, Optional<StatisticValues> statisticValues,
Optional<Date> timestamp, Unit unit, Optional<Double> value) {
this.dimensions = ImmutableSet.<Dimension> copyOf(checkNotNull(dimensions, "dimensions"));
this.metricName = checkNotNull(metricName, "metricName");
this.statisticValues = Optional.fromNullable(statisticValues);
this.timestamp = Optional.fromNullable(timestamp);
this.statisticValues = checkNotNull(statisticValues, "statisticValues");
this.timestamp = checkNotNull(timestamp, "timestamp");
this.unit = checkNotNull(unit, "unit");
this.value = checkNotNull(value, "value");
}
@ -95,13 +97,13 @@ public class MetricDatum {
/**
* return the actual value of the metric
*/
public double getValue() {
public Optional<Double> getValue() {
return value;
}
/**
* Returns a new builder. The generated builder is equivalent to the builder
* created by the {@link Builder} constructor.
* Returns a new builder. The generated builder is equivalent to the builder created by the
* {@link Builder} constructor.
*/
public static Builder builder() {
return new Builder();
@ -110,27 +112,29 @@ public class MetricDatum {
public static class Builder {
// this builder is set to be additive on dimension calls, so make this mutable
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private ImmutableList.Builder<Dimension> dimensions = ImmutableList.<Dimension> builder();
private String metricName;
private StatisticValues statisticValues;
private Date timestamp;
private Optional<StatisticValues> statisticValues = Optional.absent();
private Optional<Date> timestamp = Optional.absent();
private Unit unit = Unit.NONE;
private double value;
private Optional<Double> value = Optional.absent();
/**
* Creates a new builder. The returned builder is equivalent to the builder
* generated by {@link org.jclouds.cloudwatch.domain.MetricDatum#builder}.
* Creates a new builder. The returned builder is equivalent to the builder generated by
* {@link org.jclouds.cloudwatch.domain.MetricDatum#builder}.
*/
public Builder() {}
public Builder() {
}
/**
* A list of dimensions describing qualities of the metric.
*
* @param dimensions the dimensions describing the qualities of the metric
* @param dimensions
* the dimensions describing the qualities of the metric
*
* @return this {@code Builder} object
*/
public Builder dimensions(Set<Dimension> dimensions) {
public Builder dimensions(Iterable<Dimension> dimensions) {
this.dimensions.addAll(checkNotNull(dimensions, "dimensions"));
return this;
}
@ -138,7 +142,8 @@ public class MetricDatum {
/**
* A dimension describing qualities of the metric.
*
* @param dimension the dimension describing the qualities of the metric
* @param dimension
* the dimension describing the qualities of the metric
*
* @return this {@code Builder} object
*/
@ -150,7 +155,8 @@ public class MetricDatum {
/**
* The name of the metric.
*
* @param metricName the metric name
* @param metricName
* the metric name
*
* @return this {@code Builder} object
*/
@ -162,32 +168,35 @@ public class MetricDatum {
/**
* The object describing the set of statistical values describing the metric.
*
* @param statisticValues the object describing the set of statistical values for the metric
* @param statisticValues
* the object describing the set of statistical values for the metric
*
* @return this {@code Builder} object
*/
public Builder statisticValues(StatisticValues statisticValues) {
this.statisticValues = statisticValues;
this.statisticValues = Optional.fromNullable(statisticValues);
return this;
}
/**
* The time stamp used for the metric. If not specified, the default value is set to the time the metric data was
* received.
* The time stamp used for the metric. If not specified, the default value is set to the time
* the metric data was received.
*
* @param timestamp the time stamp used for the metric
* @param timestamp
* the time stamp used for the metric
*
* @return this {@code Builder} object
*/
public Builder timestamp(Date timestamp) {
this.timestamp = timestamp;
this.timestamp = Optional.fromNullable(timestamp);
return this;
}
/**
* The unit for the metric.
*
* @param unit the unit for the metric
* @param unit
* the unit for the metric
*
* @return this {@code Builder} object
*/
@ -199,12 +208,13 @@ public class MetricDatum {
/**
* The value for the metric.
*
* @param value the value for the metric
* @param value
* the value for the metric
*
* @return this {@code Builder} object
*/
public Builder value(double value) {
this.value = value;
public Builder value(Double value) {
this.value = Optional.fromNullable(value);
return this;
}
@ -212,7 +222,7 @@ public class MetricDatum {
* Returns a newly-created {@code MetricDatum} based on the contents of the {@code Builder}.
*/
public MetricDatum build() {
return new MetricDatum(dimensions, metricName, statisticValues, timestamp, unit, value);
return new MetricDatum(dimensions.build(), metricName, statisticValues, timestamp, unit, value);
}
}
@ -240,7 +250,8 @@ public class MetricDatum {
}
protected ToStringHelper string() {
return Objects.toStringHelper("").add("dimensions", dimensions).add("metricName", metricName).add(
"statisticValues", statisticValues).add("timestamp", timestamp).add("unit", unit).add("value", value);
return Objects.toStringHelper("").omitNullValues().add("dimensions", dimensions).add("metricName", metricName)
.add("statisticValues", statisticValues.orNull()).add("timestamp", timestamp.orNull()).add("unit", unit)
.add("value", value.orNull());
}
}

View File

@ -60,7 +60,6 @@ public class MetricDataBinderTest {
.statisticValues(ss)
.dimension(new Dimension("TestDimension", "FAKE"))
.unit(Unit.COUNT)
.value(2)
.build();
HttpRequest request = binder.bindToRequest(request(), ImmutableSet.of(metricDatum));
@ -73,8 +72,7 @@ public class MetricDataBinderTest {
"&MetricData.member.1.StatisticValues.Minimum=1.0" +
"&MetricData.member.1.StatisticValues.SampleCount=4.0" +
"&MetricData.member.1.StatisticValues.Sum=10.0" +
"&MetricData.member.1.Unit=" + Unit.COUNT.toString() +
"&MetricData.member.1.Value=2.0");
"&MetricData.member.1.Unit=" + Unit.COUNT.toString());
}
public void testMetricWithMultipleDimensions() throws Exception {

View File

@ -114,8 +114,12 @@ public class Attachment implements Comparable<Attachment> {
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -209,9 +209,12 @@ public class BundleTask implements Comparable<BundleTask> {
}
/**
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* @return region of the bundle task
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -219,9 +219,12 @@ public class Image implements Comparable<Image> {
}
/**
* AMIs are tied to the Region where its files are located within Amazon S3.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -47,8 +47,12 @@ public class InstanceStateChange implements Comparable<InstanceStateChange> {
}
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -103,8 +103,12 @@ public class KeyPair implements Comparable<KeyPair> {
}
/**
* Key pairs (to connect to instances) are Region-specific.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -42,8 +42,12 @@ public class PublicIpInstanceIdPair implements Comparable<PublicIpInstanceIdPair
}
/**
* Elastic IP addresses are tied to a Region and cannot be mapped across Regions.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -156,8 +156,12 @@ public class Reservation<T extends RunningInstance> extends ForwardingSet<T> imp
}
/**
* Instances are tied to Availability Zones. However, the instance ID is tied to the Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -46,6 +46,13 @@ public class ReservedInstancesOffering implements Comparable<ReservedInstancesOf
this.usagePrice = usagePrice;
}
/**
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -290,8 +290,12 @@ public class RunningInstance implements Comparable<RunningInstance> {
}
/**
* Instance Ids are scoped to the region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -51,11 +51,12 @@ public class SecurityGroup implements Comparable<SecurityGroup> {
}
/**
* Security groups are not copied across Regions. Instances within the Region
* cannot communicate with instances outside the Region using group-based
* firewall rules. Traffic from instances in another Region is seen as WAN
* bandwidth.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -75,8 +75,12 @@ public class Snapshot implements Comparable<Snapshot> {
}
/**
* Snapshots are tied to Regions and can only be used for volumes within the same Region.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -172,9 +172,12 @@ public class Volume implements Comparable<Volume> {
}
/**
* An Amazon EBS volume must be located within the same Availability Zone as the instance to
* which it attaches.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -156,7 +156,7 @@ public interface NovaApi {
* Provides synchronous access to Server Admin Actions features.
*/
@Delegate
Optional<? extends ServerAdminApi> getAdminActionsExtensionForZone(
Optional<? extends ServerAdminApi> getServerAdminExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**

View File

@ -155,7 +155,7 @@ public interface NovaAsyncApi {
* Provides asynchronous access to Server Admin Actions features.
*/
@Delegate
Optional<? extends ServerAdminAsyncApi> getAdminActionsExtensionForZone(
Optional<? extends ServerAdminAsyncApi> getServerAdminExtensionForZone(
@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
/**

View File

@ -249,8 +249,8 @@ public class NovaComputeServiceAdapter implements
@Override
public void resumeNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().resume(zoneAndId.getId());
if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().resume(zoneAndId.getId());
}
throw new UnsupportedOperationException("resume requires installation of the Admin Actions extension");
}
@ -258,8 +258,8 @@ public class NovaComputeServiceAdapter implements
@Override
public void suspendNode(String id) {
ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
if (novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getAdminActionsExtensionForZone(zoneAndId.getZone()).get().suspend(zoneAndId.getId());
if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().suspend(zoneAndId.getId());
}
throw new UnsupportedOperationException("suspend requires installation of the Admin Actions extension");
}

View File

@ -52,7 +52,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.suspend("1"));
}
@ -64,7 +64,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.suspend("1"));
}
@ -77,7 +77,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "suspend").build(),
HttpResponse.builder().statusCode(403).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
api.suspend("1");
}
@ -89,7 +89,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.resume("1"));
}
@ -101,7 +101,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.resume("1"));
}
@ -114,7 +114,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "resume").build(),
HttpResponse.builder().statusCode(403).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
api.resume("1");
}
@ -126,7 +126,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "lock").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.lock("1"));
}
@ -138,7 +138,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "lock").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.lock("1"));
}
@ -150,7 +150,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "unlock").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.unlock("1"));
}
@ -162,7 +162,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "unlock").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.unlock("1"));
}
@ -174,7 +174,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "pause").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.pause("1"));
}
@ -186,7 +186,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "pause").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.pause("1"));
}
@ -198,7 +198,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "unpause").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.unpause("1"));
}
@ -210,7 +210,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "unpause").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.unpause("1"));
}
@ -222,7 +222,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "migrate").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.migrate("1"));
}
@ -235,7 +235,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "migrate").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.migrate("1"));
}
@ -247,7 +247,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "resetNetwork").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.resetNetwork("1"));
}
@ -259,7 +259,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "resetNetwork").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.resetNetwork("1"));
}
@ -271,7 +271,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "injectNetworkInfo").build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.injectNetworkInfo("1"));
}
@ -283,7 +283,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
standardActionRequestBuilderVoidResponse(endpoint, "injectNetworkInfo").build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.injectNetworkInfo("1"));
}
@ -295,7 +295,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
authenticatedGET().endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/1/action").method("POST")
.payload(payloadFromStringWithContentType("{\"createBackup\":{\"backup_type\":\"weekly\",\"rotation\":3,\"name\":\"mybackup\",\"metadata\":{\"some\":\"data or other\"}}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(202).addHeader("Location", "http://172.16.89.149:8774/v2/images/1976b3b3-409a-468d-b16c-a9172c341b46").build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
String imageId = api.createBackup("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
assertEquals(imageId, "1976b3b3-409a-468d-b16c-a9172c341b46");
@ -310,7 +310,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
authenticatedGET().endpoint(endpoint).method("POST")
.payload(payloadFromStringWithContentType("{\"createBackup\":{\"backup_type\":\"weekly\",\"rotation\":3,\"name\":\"mybackup\",\"metadata\":{\"some\":\"data or other\"}}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
api.createBackup("1", "mybackup", BackupType.WEEKLY, 3, CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("some", "data or other")));
}
@ -323,7 +323,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
standardActionRequestBuilderVoidResponse(endpoint, "GONNAOVERWRITE")
.payload(payloadFromStringWithContentType("{\"os-migrateLive\":{\"host\":\"bighost\",\"block_migration\":true,\"disk_over_commit\":false}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(202).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertTrue(api.liveMigrate("1", "bighost", true, false));
}
@ -336,7 +336,7 @@ public class AdminActionsApiExpectTest extends BaseNovaApiExpectTest {
standardActionRequestBuilderVoidResponse(endpoint, "GONNAOVERWRITE")
.payload(payloadFromStringWithContentType("{\"os-migrateLive\":{\"host\":\"bighost\",\"block_migration\":true,\"disk_over_commit\":false}}", MediaType.APPLICATION_JSON)).build(),
HttpResponse.builder().statusCode(404).build()
).getAdminActionsExtensionForZone("az-1.region-a.geo-1").get();
).getServerAdminExtensionForZone("az-1.region-a.geo-1").get();
assertFalse(api.liveMigrate("1", "bighost", true, false));
}

View File

@ -32,6 +32,7 @@ import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.testng.SkipException;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeGroups;
@ -59,7 +60,7 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
private String testServerId;
private String backupImageId;
@BeforeGroups(groups = {"integration", "live"})
@BeforeGroups(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
@ -67,7 +68,7 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
serverApi = novaContext.getApi().getServerApiForZone(zone);
extensionApi = novaContext.getApi().getExtensionApiForZone(zone);
imageApi = novaContext.getApi().getImageApiForZone(zone);
apiOption = novaContext.getApi().getAdminActionsExtensionForZone(zone);
apiOption = novaContext.getApi().getServerAdminExtensionForZone(zone);
if (apiOption.isPresent()) {
testServerId = createServerInZone(zone).getId();
}
@ -87,13 +88,20 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
super.tearDown();
}
protected void skipOnAdminExtensionAbsent() {
if (!apiOption.isPresent()) {
throw new SkipException("Test depends on ServerAdminApi extension");
}
}
@AfterMethod(alwaysRun = true)
public void ensureServerIsActiveAgain() {
if (apiOption.isPresent())
blockUntilServerInState(testServerId, serverApi, Status.ACTIVE);
}
public void testSuspendAndResume() {
if (apiOption.isPresent()) {
skipOnAdminExtensionAbsent();
ServerAdminApi api = apiOption.get();
// Suspend-resume
@ -116,11 +124,11 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
fail("Resumed an already resumed server!");
} catch (HttpResponseException e) {
}
}
}
public void testLockAndUnlock() {
if (apiOption.isPresent()) {
skipOnAdminExtensionAbsent();
ServerAdminApi api = apiOption.get();
// TODO should we be able to double-lock (as it were)
@ -130,20 +138,19 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
assertTrue(api.lock(testServerId));
assertTrue(api.unlock(testServerId));
assertTrue(api.unlock(testServerId));
}
}
public void testResetNetworkAndInjectNetworkInfo() {
if (apiOption.isPresent()) {
skipOnAdminExtensionAbsent();
ServerAdminApi api = apiOption.get();
assertTrue(api.resetNetwork(testServerId));
assertTrue(api.injectNetworkInfo(testServerId));
}
}
@Test
public void testPauseAndUnpause() {
if (apiOption.isPresent()) {
skipOnAdminExtensionAbsent();
ServerAdminApi api = apiOption.get();
// Unlock and lock (double-checking error contitions too)
@ -166,12 +173,12 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
fail("Unpaused a server we just unpaused!");
} catch (HttpResponseException e) {
}
}
}
@Test
public void testCreateBackupOfServer() throws InterruptedException {
if (apiOption.isPresent()) {
skipOnAdminExtensionAbsent();
backupImageId = apiOption.get().createBackup(testServerId, "jclouds-test-backup", BackupType.DAILY, 0,
CreateBackupOfServerOptions.Builder.metadata(ImmutableMap.of("test", "metadata")));
@ -187,5 +194,4 @@ public class AdminActionsApiLiveTest extends BaseNovaApiLiveTest {
Image backupImage = imageApi.get(backupImageId);
assertEquals(backupImage.getId(), backupImageId);
}
}
}

View File

@ -69,10 +69,10 @@ public class ImageApiLiveTest extends BaseNovaApiLiveTest {
assertTrue(image.getMinRam() > 0);
assertTrue(image.getProgress() >= 0 && image.getProgress() <= 100);
assertNotNull(image.getStatus());
assertNotNull(image.getServer());
assertNotNull(image.getTenantId());
assertNotNull(image.getUpdated());
assertNotNull(image.getUserId());
// image.getServer() can be null
// image.getTenantId() can be null
// image.getUpdated() can be null
// image.getUserId() can be null
}
}
}

View File

@ -19,9 +19,9 @@
package org.jclouds.openstack.nova.v2_0.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.*;
import java.util.Set;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.openstack.nova.v2_0.domain.Server;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
@ -44,12 +44,7 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
public void testListServers() throws Exception {
for (String zoneId : zones) {
ServerApi api = novaContext.getApi().getServerApiForZone(zoneId);
Set<? extends Resource> response = api.list().concat().toImmutableSet();
assertNotNull(response);
assertFalse(response.isEmpty());
assert null != response;
assertTrue(response.size() >= 0);
for (Resource server : response) {
for (Resource server : api.list().concat()) {
checkResource(server);
}
}
@ -59,10 +54,7 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
public void testListServersInDetail() throws Exception {
for (String zoneId : zones) {
ServerApi api = novaContext.getApi().getServerApiForZone(zoneId);
Set<? extends Server> response = api.listInDetail().concat().toImmutableSet();
assertNotNull(response);
assertFalse(response.isEmpty());
for (Server server : response) {
for (Server server : api.listInDetail().concat()) {
checkServer(server);
}
}
@ -72,8 +64,7 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest {
public void testGetServerById() throws Exception {
for (String zoneId : zones) {
ServerApi api = novaContext.getApi().getServerApiForZone(zoneId);
Set<? extends Resource> response = api.list().concat().toImmutableSet();
for (Resource server : response) {
for (Resource server : api.list().concat()) {
Server details = api.get(server.getId());
assertEquals(details.getId(), server.getId());
assertEquals(details.getName(), server.getName());

View File

@ -64,7 +64,8 @@ public class SQSErrorRetryHandlerTest {
Stopwatch watch = new Stopwatch().start();
assertTrue(retry.shouldRetryRequestOnError(command, response, error));
assertEquals(command.getFailureCount(), 60);
assertTrue(watch.stop().elapsedTime(TimeUnit.MILLISECONDS) >= 100);
// allow for slightly inaccurate system timers
assertTrue(watch.stop().elapsedTime(TimeUnit.MILLISECONDS) >= 98);
}

View File

@ -140,6 +140,7 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
@ -1014,7 +1015,7 @@ public class RestAnnotationProcessor<T> {
Annotation[] annotations = request.getJavaMethod().getParameterAnnotations()[entry.getKey()];
for (Annotation a : annotations) {
if (Nullable.class.isAssignableFrom(a.annotationType()))
if (NULLABLE.apply(a))
continue OUTER;
}
Preconditions.checkNotNull(null, request.getJavaMethod().getName() + " parameter " + (entry.getKey() + 1));
@ -1188,17 +1189,11 @@ public class RestAnnotationProcessor<T> {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((PathParam) key).value();
String paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
paramValue = args[entry.getKey()].toString();
}
pathParamValues.put(paramKey, paramValue);
Optional<?> paramValue = getParamValue(method, args, extractors, entry, paramKey);
if (paramValue.isPresent())
pathParamValues.put(paramKey, paramValue.get().toString());
}
}
if (method.isAnnotationPresent(PathParam.class) && method.isAnnotationPresent(ParamParser.class)) {
String paramKey = method.getAnnotation(PathParam.class).value();
String paramValue = injector.getInstance(method.getAnnotation(ParamParser.class).value()).apply(args);
@ -1208,6 +1203,33 @@ public class RestAnnotationProcessor<T> {
return pathParamValues;
}
protected Optional<?> getParamValue(Method method, Object[] args, Set<Annotation> extractors,
Entry<Integer, Set<Annotation>> entry, String paramKey) {
Object arg = args[entry.getKey()];
if (arg == null && containsNullable(method.getParameterAnnotations()[entry.getKey()]))
return Optional.absent();
checkNotNull(arg, "param{%s} for method %s.%s", paramKey, method.getDeclaringClass().getSimpleName(),
method.getName());
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
return Optional.of(injector.getInstance(extractor.value()).apply(arg));
}
return Optional.of(arg);
}
private static final Predicate<Annotation> NULLABLE = new Predicate<Annotation>() {
@Override
public boolean apply(Annotation in) {
return Nullable.class.isAssignableFrom(in.annotationType());
}
};
private static boolean containsNullable(Annotation[] annotations) {
return Iterables.any(ImmutableSet.copyOf(annotations), NULLABLE);
}
private Multimap<String, String> encodeValues(Multimap<String, String> unencoded, char... skips) {
Multimap<String, String> encoded = LinkedHashMultimap.create();
for (Entry<String, String> entry : unencoded.entries()) {
@ -1226,14 +1248,9 @@ public class RestAnnotationProcessor<T> {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((MatrixParam) key).value();
String paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
paramValue = args[entry.getKey()].toString();
}
matrixParamValues.put(paramKey, paramValue);
Optional<?> paramValue = getParamValue(method, args, extractors, entry, paramKey);
if (paramValue.isPresent())
matrixParamValues.put(paramKey, paramValue.get().toString());
}
}
@ -1257,16 +1274,9 @@ public class RestAnnotationProcessor<T> {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((FormParam) key).value();
String paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
Object pvo = args[entry.getKey()];
Preconditions.checkNotNull(pvo, paramKey);
paramValue = pvo.toString();
}
formParamValues.put(paramKey, paramValue);
Optional<?> paramValue = getParamValue(method, args, extractors, entry, paramKey);
if (paramValue.isPresent())
formParamValues.put(paramKey, paramValue.get().toString());
}
}
@ -1289,16 +1299,9 @@ public class RestAnnotationProcessor<T> {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((QueryParam) key).value();
Object paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
paramValue = args[entry.getKey()];
}
if (paramValue != null) {
queryParamValues.put(paramKey, paramValue.toString());
}
Optional<?> paramValue = getParamValue(method, args, extractors, entry, paramKey);
if (paramValue.isPresent())
queryParamValues.put(paramKey, paramValue.get().toString());
}
}
@ -1321,15 +1324,9 @@ public class RestAnnotationProcessor<T> {
for (Annotation key : entry.getValue()) {
Set<Annotation> extractors = indexToParamExtractor.get(entry.getKey());
String paramKey = ((PayloadParam) key).value();
Object paramValue;
if (extractors != null && extractors.size() > 0) {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
paramValue = args[entry.getKey()] != null ? args[entry.getKey()] : null;
}
postParams.put(paramKey, paramValue);
Optional<?> paramValue = getParamValue(method, args, extractors, entry, paramKey);
if (paramValue.isPresent())
postParams.put(paramKey, paramValue.get());
}
}
return postParams;

View File

@ -499,6 +499,12 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
@QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" })
public void foo3(@QueryParam("robbie") String robbie) {
}
@FOO
@Path("/")
@QueryParams(keys = { "foo", "fooble" }, values = { "bar", "baz" })
public void foo3Nullable(@Nullable @QueryParam("robbie") String robbie) {
}
}
public void testUnEncodeQuery() {
@ -538,6 +544,25 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
assertEquals(request.getMethod(), "FOO");
}
@Test
public void testNiceNPEQueryParam() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestQuery.class.getMethod("foo3", String.class);
try {
factory(TestPath.class).createRequest(method, (String) null);
} catch (NullPointerException e) {
assertEquals(e.getMessage(), "param{robbie} for method TestQuery.foo3");
}
}
public void testNoNPEOnQueryParamWithNullable() throws SecurityException, NoSuchMethodException {
Method method = TestQuery.class.getMethod("foo3Nullable", String.class);
HttpRequest request = factory(TestPath.class).createRequest(method, (String) null);
assertEquals(request.getEndpoint().getHost(), "localhost");
assertEquals(request.getEndpoint().getPath(), "/");
assertEquals(request.getEndpoint().getQuery(), "foo=bar&fooble=baz");
assertEquals(request.getMethod(), "FOO");
}
public interface TestPayloadParamVarargs {
@POST
public void varargs(HttpRequestOptions... options);
@ -1398,6 +1423,11 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
public void onePath(@PathParam("path") String path) {
}
@GET
@Path("/{path}")
public void onePathNullable(@Nullable @PathParam("path") String path) {
}
@GET
@Path("/{path1}/{path2}")
public void twoPaths(@PathParam("path1") String path, @PathParam("path2") String path2) {
@ -1436,6 +1466,16 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
}
}
@Test
public void testNiceNPEPathParam() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPath.class.getMethod("onePath", String.class);
try {
factory(TestPath.class).createRequest(method, (String) null);
} catch (NullPointerException e) {
assertEquals(e.getMessage(), "param{path} for method TestPath.onePath");
}
}
@Test
public void testPathParamExtractor() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPath.class.getMethod("onePathParamExtractor", String.class);
@ -1463,6 +1503,16 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
assertPayloadEquals(request, null, null, false);
}
@Test
public void testNiceNPEMatrixParam() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPath.class.getMethod("oneMatrixParamExtractor", String.class);
try {
factory(TestPath.class).createRequest(method, (String) null);
} catch (NullPointerException e) {
assertEquals(e.getMessage(), "param{one} for method TestPath.oneMatrixParamExtractor");
}
}
@Test
public void testFormParamExtractor() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPath.class.getMethod("oneFormParamExtractor", String.class);
@ -1472,6 +1522,16 @@ public class RestAnnotationProcessorTest extends BaseRestApiTest {
assertPayloadEquals(request, "one=l", "application/x-www-form-urlencoded", false);
}
@Test
public void testNiceNPEFormParam() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPath.class.getMethod("oneFormParamExtractor", String.class);
try {
factory(TestPath.class).createRequest(method, (String) null);
} catch (NullPointerException e) {
assertEquals(e.getMessage(), "param{one} for method TestPath.oneFormParamExtractor");
}
}
@Test
public void testParamExtractorMethod() throws SecurityException, NoSuchMethodException {
Method method = TestPath.class.getMethod("onePathParamExtractorMethod", String.class);

View File

@ -77,8 +77,12 @@ public class PlacementGroup implements Comparable<PlacementGroup> {
}
/**
* @return placement groups are in a region, however the namescope is global.
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}

View File

@ -92,6 +92,13 @@ public class Spot implements Comparable<Spot> {
this.timestamp = checkNotNull(timestamp, "timestamp");
}
/**
* To be removed in jclouds 1.6 <h4>Warning</h4>
*
* Especially on EC2 clones that may not support regions, this value is fragile. Consider
* alternate means to determine context.
*/
@Deprecated
public String getRegion() {
return region;
}