refined cloudwatch to match elb, particularly PaginatedSet and Options consistency

This commit is contained in:
Adrian Cole 2012-07-09 00:03:50 -07:00
parent 0d82a61142
commit c47950c9ab
11 changed files with 206 additions and 240 deletions

View File

@ -18,16 +18,16 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import java.util.Iterator;
import java.util.List; import java.util.List;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum; import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.features.MetricClient; import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.collect.PaginatedSets;
import com.google.common.collect.AbstractIterator; import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
/** /**
@ -46,43 +46,18 @@ public class CloudWatch {
* @return iterable of metrics fitting the criteria * @return iterable of metrics fitting the criteria
*/ */
public static Iterable<Metric> listMetrics(final MetricClient metricClient, final ListMetricsOptions options) { public static Iterable<Metric> listMetrics(final MetricClient metricClient, final ListMetricsOptions options) {
return new Iterable<Metric>() { return PaginatedSets.lazyContinue(metricClient.list(options), new Function<String, PaginatedSet<Metric>>() {
public Iterator<Metric> iterator() {
return new AbstractIterator<Metric>() {
private ListMetricsOptions lastOptions = options; @Override
private ListMetricsResponse response = metricClient.listMetrics(lastOptions); public PaginatedSet<Metric> apply(String input) {
private Iterator<Metric> iterator = response.iterator(); return metricClient.list(options.clone().nextMarker(input));
/**
* {@inheritDoc}
*/
@Override
protected Metric computeNext() {
while (true) {
if (iterator == null) {
lastOptions = ListMetricsOptions.builder()
.namespace(lastOptions.getNamespace())
.metricName(lastOptions.getMetricName())
.dimensions(lastOptions.getDimensions())
.nextToken(lastOptions.getNextToken())
.build();
response = metricClient.listMetrics(lastOptions);
iterator = response.iterator();
}
if (iterator.hasNext()) {
return iterator.next();
}
if (response.getNextToken() == null) {
return endOfData();
}
iterator = null;
}
}
};
} }
};
@Override
public String toString() {
return "listMetrics(" + options + ")";
}
});
} }
/** /**
@ -112,7 +87,7 @@ public class CloudWatch {
MetricClient metricClient = cloudWatchClient.getMetricClientForRegion(region); MetricClient metricClient = cloudWatchClient.getMetricClientForRegion(region);
for (List<MetricDatum> slice : Iterables.partition(metrics, 10)) { for (List<MetricDatum> slice : Iterables.partition(metrics, 10)) {
metricClient.putMetricData(slice, namespace); metricClient.putMetricsInNamespace(slice, namespace);
} }
} }

View File

@ -87,6 +87,9 @@ public interface CloudWatchAsyncClient {
/** /**
* Provides asynchronous access to Metric features. * Provides asynchronous access to Metric features.
*/ */
@Delegate
MetricAsyncClient getMetricClient();
@Delegate @Delegate
MetricAsyncClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); MetricAsyncClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);

View File

@ -95,6 +95,12 @@ public interface CloudWatchClient {
Set<Datapoint> getMetricStatisticsInRegion(@Nullable String region, String metricName, String namespace, Set<Datapoint> getMetricStatisticsInRegion(@Nullable String region, String metricName, String namespace,
Date startTime, Date endTime, int period, Statistics statistics, GetMetricStatisticsOptions... options); Date startTime, Date endTime, int period, Statistics statistics, GetMetricStatisticsOptions... options);
/**
* Provides synchronous access to Metric features.
*/
@Delegate
MetricClient getMetricClient();
/** /**
* Provides synchronous access to Metric features. * Provides synchronous access to Metric features.
*/ */

View File

@ -18,27 +18,29 @@
*/ */
package org.jclouds.cloudwatch.features; package org.jclouds.cloudwatch.features;
import com.google.common.util.concurrent.ListenableFuture; import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.cloudwatch.binders.GetMetricStatisticsBinder; import org.jclouds.cloudwatch.binders.GetMetricStatisticsBinder;
import org.jclouds.cloudwatch.binders.MetricDataBinder; import org.jclouds.cloudwatch.binders.MetricDataBinder;
import org.jclouds.cloudwatch.domain.GetMetricStatistics; import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse; import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum; import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions; import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandlerV2; import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandlerV2;
import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler; import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.annotations.XMLResponseParser;
import javax.ws.rs.FormParam; import com.google.common.util.concurrent.ListenableFuture;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
/** /**
* Provides access to Amazon CloudWatch via the Query API * Provides access to Amazon CloudWatch via the Query API
@ -52,22 +54,22 @@ import javax.ws.rs.Path;
public interface MetricAsyncClient { public interface MetricAsyncClient {
/** /**
* @see MetricClient#listMetrics() * @see MetricClient#list()
*/ */
@POST @POST
@Path("/") @Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class) @XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics") @FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics(); ListenableFuture<? extends PaginatedSet<Metric>> list();
/** /**
* @see MetricClient#listMetrics(ListMetricsOptions) * @see MetricClient#list(ListMetricsOptions)
*/ */
@POST @POST
@Path("/") @Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class) @XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics") @FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics(ListMetricsOptions options); ListenableFuture<? extends PaginatedSet<Metric>> list(ListMetricsOptions options);
/** /**
* @see MetricClient#getMetricStatistics(GetMetricStatistics) * @see MetricClient#getMetricStatistics(GetMetricStatistics)
@ -91,12 +93,12 @@ public interface MetricAsyncClient {
GetMetricStatisticsOptions options); GetMetricStatisticsOptions options);
/** /**
* @see MetricClient#putMetricData(Iterable, String) * @see MetricClient#putMetricsInNamespace(Iterable, String)
*/ */
@POST @POST
@Path("/") @Path("/")
@FormParams(keys = "Action", values = "PutMetricData") @FormParams(keys = "Action", values = "PutMetricData")
ListenableFuture<Void> putMetricData(@BinderParam(MetricDataBinder.class) Iterable<MetricDatum> metrics, ListenableFuture<Void> putMetricsInNamespace(@BinderParam(MetricDataBinder.class) Iterable<MetricDatum> metrics,
@FormParam("Namespace") String namespace); @FormParam("Namespace") String namespace);
} }

View File

@ -18,16 +18,17 @@
*/ */
package org.jclouds.cloudwatch.features; package org.jclouds.cloudwatch.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudwatch.domain.GetMetricStatistics; import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse; import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum; import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions; import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import java.util.concurrent.TimeUnit;
/** /**
* Provides access to Amazon CloudWatch via the Query API * Provides access to Amazon CloudWatch via the Query API
* <p/> * <p/>
@ -53,9 +54,9 @@ public interface MetricClient {
* *
* @return the response object * @return the response object
*/ */
ListMetricsResponse listMetrics(ListMetricsOptions options); PaginatedSet<Metric> list(ListMetricsOptions options);
ListMetricsResponse listMetrics(); PaginatedSet<Metric> list();
/** /**
* Gets statistics for the specified metric. * Gets statistics for the specified metric.
@ -75,6 +76,6 @@ public interface MetricClient {
* @param metrics the metrics to publish * @param metrics the metrics to publish
* @param namespace the namespace to publish the metrics to * @param namespace the namespace to publish the metrics to
*/ */
void putMetricData(Iterable<MetricDatum> metrics, String namespace); void putMetricsInNamespace(Iterable<MetricDatum> metrics, String namespace);
} }

View File

@ -18,12 +18,15 @@
*/ */
package org.jclouds.cloudwatch.options; package org.jclouds.cloudwatch.options;
import com.google.common.collect.Sets; import java.util.Set;
import org.jclouds.cloudwatch.domain.Dimension; import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.javax.annotation.Nullable;
import java.util.Set; import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
/** /**
* Options used to list available metrics. * Options used to list available metrics.
@ -32,169 +35,148 @@ import java.util.Set;
* *
* @author Jeremy Whitlock * @author Jeremy Whitlock
*/ */
public class ListMetricsOptions extends BaseHttpRequestOptions { public class ListMetricsOptions extends BaseHttpRequestOptions implements Cloneable {
private final Set<Dimension> dimensions; private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private final String metricName; private String metricName;
private final String namespace; private String namespace;
private final String nextToken; private String nextToken;
/** /**
* Private constructor to enforce using {@link Builder}. * The namespace to filter against.
*
* @param namespace the namespace to filter against
*
* @return this {@code Builder} object
*/ */
private ListMetricsOptions(@Nullable String namespace, @Nullable String metricName, public ListMetricsOptions namespace(String namespace) {
@Nullable Set<Dimension> dimensions, @Nullable String nextToken) {
this.dimensions = dimensions;
this.metricName = metricName;
this.namespace = namespace; this.namespace = namespace;
return this;
}
/**
* The name of the metric to filter against.
*
* @param metricName the metric name to filter against
*
* @return this {@code Builder} object
*/
public ListMetricsOptions metricName(String metricName) {
this.metricName = metricName;
return this;
}
/**
* A list of dimensions to filter against.
*
* @param dimensions the dimensions to filter against
*
* @return this {@code Builder} object
*/
public ListMetricsOptions dimensions(Iterable<Dimension> dimensions) {
Iterables.addAll(this.dimensions, dimensions);
return this;
}
/**
* A dimension to filter the available metrics by.
*
* @param dimension a dimension to filter the returned metrics by
*
* @return this {@code Builder} object
*/
public ListMetricsOptions dimension(Dimension dimension) {
this.dimensions.add(dimension);
return this;
}
/**
* The token returned by a previous call to indicate that there is more data available.
*
* @param nextToken the next token indicating that there is more data available
*
* @return this {@code Builder} object
*/
public ListMetricsOptions nextMarker(String nextToken) {
this.nextToken = nextToken; this.nextToken = nextToken;
return this;
} }
/** /**
* return the set of dimensions for this request * Returns a newly-created {@code ListMetricsOptions} based on the contents of
* the {@code Builder}.
*/ */
@Nullable @Override
public Set<Dimension> getDimensions() { public Multimap<String, String> buildFormParameters() {
return dimensions; ImmutableMultimap.Builder<String, String> formParameters = ImmutableMultimap.<String, String>builder();
} int dimensionIndex = 1;
/** // If namespace isn't specified, don't include it
* return the metric name for this request if (namespace != null) {
*/ formParameters.put("Namespace", namespace);
@Nullable }
public String getMetricName() { // If metricName isn't specified, don't include it
return metricName; if (metricName != null) {
} formParameters.put("MetricName", metricName);
}
/** // If dimensions isn't specified, don't include it
* return the namespace for this request if (dimensions != null) {
*/ for (Dimension dimension : dimensions) {
@Nullable formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
public String getNamespace() { formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
return namespace; dimensionIndex++;
} }
}
/** // If nextToken isn't specified, don't include it
* return the next token for this request if (nextToken != null) {
*/ formParameters.put("NextToken", nextToken);
@Nullable }
public String getNextToken() {
return nextToken;
}
/** return formParameters.build();
* 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();
} }
@Override
public ListMetricsOptions clone() {
return Builder.namespace(namespace).metricName(metricName).dimensions(dimensions).nextMarker(nextToken);
}
public static class Builder { public static class Builder {
private Set<Dimension> dimensions = Sets.newLinkedHashSet();
private String metricName;
private String namespace;
private String nextToken;
/** /**
* Creates a new builder. The returned builder is equivalent to the builder * @see ListMetricsOptions#namespace(String)
* generated by {@link ListMetricsOptions#builder}.
*/ */
public Builder() {} public static ListMetricsOptions namespace(String namespace) {
return new ListMetricsOptions().namespace(namespace);
/**
* The namespace to filter against.
*
* @param namespace the namespace to filter against
*
* @return this {@code Builder} object
*/
public Builder namespace(String namespace) {
this.namespace = namespace;
return this;
} }
/** /**
* The name of the metric to filter against. * @see ListMetricsOptions#metricName(String)
*
* @param metricName the metric name to filter against
*
* @return this {@code Builder} object
*/ */
public Builder metricName(String metricName) { public static ListMetricsOptions metricName(String metricName) {
this.metricName = metricName; return new ListMetricsOptions().metricName(metricName);
return this;
} }
/** /**
* A list of dimensions to filter against. * @see ListMetricsOptions#dimensions(Iterable)
*
* @param dimensions the dimensions to filter against
*
* @return this {@code Builder} object
*/ */
public Builder dimensions(Set<Dimension> dimensions) { public static ListMetricsOptions dimensions(Iterable<Dimension> dimensions) {
this.dimensions = dimensions; return new ListMetricsOptions().dimensions(dimensions);
return this;
} }
/** /**
* A dimension to filter the available metrics by. * @see ListMetricsOptions#dimension(String)
*
* @param dimension a dimension to filter the returned metrics by
*
* @return this {@code Builder} object
*/ */
public Builder dimension(Dimension dimension) { public static ListMetricsOptions dimension(Dimension dimension) {
this.dimensions.add(dimension); return new ListMetricsOptions().dimension(dimension);
return this;
} }
/** /**
* The token returned by a previous call to indicate that there is more data available. * @see ListMetricsOptions#nextMarker(String)
*
* @param nextToken the next token indicating that there is more data available
*
* @return this {@code Builder} object
*/ */
public Builder nextToken(String nextToken) { public static ListMetricsOptions nextMarker(String nextToken) {
this.nextToken = nextToken; return new ListMetricsOptions().nextMarker(nextToken);
return this;
}
/**
* Returns a newly-created {@code ListMetricsOptions} based on the contents of
* the {@code Builder}.
*/
public ListMetricsOptions build() {
ListMetricsOptions lmo = new ListMetricsOptions(namespace, metricName, dimensions, nextToken);
int dimensionIndex = 1;
// If namespace isn't specified, don't include it
if (namespace != null) {
lmo.formParameters.put("Namespace", namespace);
}
// If metricName isn't specified, don't include it
if (metricName != null) {
lmo.formParameters.put("MetricName", metricName);
}
// If dimensions isn't specified, don't include it
if (dimensions != null) {
for (Dimension dimension : dimensions) {
lmo.formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
lmo.formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
}
// If nextToken isn't specified, don't include it
if (nextToken != null) {
lmo.formParameters.put("NextToken", nextToken);
}
return lmo;
} }
} }

View File

@ -18,23 +18,24 @@
*/ */
package org.jclouds.cloudwatch.xml; package org.jclouds.cloudwatch.xml;
import com.google.common.collect.Sets; import java.util.Set;
import com.google.inject.Inject;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.SaxUtils; import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import java.util.Set; import com.google.common.collect.Sets;
import com.google.inject.Inject;
/** /**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" /> * @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_ListMetrics.html" />
* *
* @author Jeremy Whitlock * @author Jeremy Whitlock
*/ */
public class ListMetricsResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<ListMetricsResponse> { public class ListMetricsResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<PaginatedSet<Metric>> {
private final MetricHandler metricHandler; private final MetricHandler metricHandler;
@ -52,8 +53,8 @@ public class ListMetricsResponseHandler extends ParseSax.HandlerForGeneratedRequ
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public ListMetricsResponse getResult() { public PaginatedSet<Metric> getResult() {
return new ListMetricsResponse(metrics, nextToken); return PaginatedSet.copyOfWithMarker(metrics, nextToken);
} }
/** /**

View File

@ -67,7 +67,7 @@ public class CloudWatchLiveTest extends BaseContextLiveTest<RestContext<CloudWat
@Test @Test
protected void testCloudWatchListMetrics() { protected void testCloudWatchListMetrics() {
// Just make sure there is at least one metric returned (Much better if the account you use has more than 500) // Just make sure there is at least one metric returned (Much better if the account you use has more than 500)
checkArgument(CloudWatch.listMetrics(client, null, ListMetricsOptions.builder().build()).iterator().hasNext()); checkArgument(CloudWatch.listMetrics(client, null, new ListMetricsOptions()).iterator().hasNext());
} }
@Test @Test
@ -89,9 +89,8 @@ public class CloudWatchLiveTest extends BaseContextLiveTest<RestContext<CloudWat
CloudWatch.putMetricData(client, null, metrics, namespace); CloudWatch.putMetricData(client, null, metrics, namespace);
ListMetricsOptions lmo = ListMetricsOptions.builder().namespace(namespace) ListMetricsOptions lmo = ListMetricsOptions.Builder.namespace(namespace)
.dimension(new Dimension("BaseMetricName", metricName)) .dimension(new Dimension("BaseMetricName", metricName));
.build();
boolean success = new RetryablePredicate<ListMetricsOptions>(new Predicate<ListMetricsOptions>() { boolean success = new RetryablePredicate<ListMetricsOptions>(new Predicate<ListMetricsOptions>() {
@Override @Override
public boolean apply(ListMetricsOptions options) { public boolean apply(ListMetricsOptions options) {

View File

@ -26,11 +26,11 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.easymock.EasyMock; import org.easymock.EasyMock;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum; import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.features.MetricClient; import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.collect.PaginatedSet;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -56,14 +56,14 @@ public class CloudWatchTest {
public void testSinglePageResult() throws Exception { public void testSinglePageResult() throws Exception {
CloudWatchClient client = createMock(CloudWatchClient.class); CloudWatchClient client = createMock(CloudWatchClient.class);
MetricClient metricClient = createMock(MetricClient.class); MetricClient metricClient = createMock(MetricClient.class);
ListMetricsOptions options = ListMetricsOptions.builder().build(); ListMetricsOptions options = new ListMetricsOptions();
ListMetricsResponse response = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null); PaginatedSet<Metric> response = PaginatedSet.copyOfWithMarker(ImmutableSet.of(createMock(Metric.class)), null);
expect(client.getMetricClientForRegion(null)) expect(client.getMetricClientForRegion(null))
.andReturn(metricClient) .andReturn(metricClient)
.atLeastOnce(); .atLeastOnce();
expect(metricClient.listMetrics(options)) expect(metricClient.list(options))
.andReturn(response) .andReturn(response)
.once(); .once();
@ -82,19 +82,19 @@ public class CloudWatchTest {
public void testMultiPageResult() throws Exception { public void testMultiPageResult() throws Exception {
CloudWatchClient client = createMock(CloudWatchClient.class); CloudWatchClient client = createMock(CloudWatchClient.class);
MetricClient metricClient = createMock(MetricClient.class); MetricClient metricClient = createMock(MetricClient.class);
ListMetricsOptions options = ListMetricsOptions.builder().build(); ListMetricsOptions options = new ListMetricsOptions();
ListMetricsResponse response1 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), "NEXTTOKEN"); PaginatedSet<Metric> response1 = PaginatedSet.copyOfWithMarker(ImmutableSet.of(createMock(Metric.class)), "NEXTTOKEN");
ListMetricsResponse response2 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null); PaginatedSet<Metric> response2 = PaginatedSet.copyOfWithMarker(ImmutableSet.of(createMock(Metric.class)), null);
// Using EasyMock.eq("") because EasyMock makes it impossible to pass null as a String value here // Using EasyMock.eq("") because EasyMock makes it impossible to pass null as a String value here
expect(client.getMetricClientForRegion(EasyMock.eq(""))) expect(client.getMetricClientForRegion(EasyMock.eq("")))
.andReturn(metricClient) .andReturn(metricClient)
.atLeastOnce(); .atLeastOnce();
expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class))) expect(metricClient.list(anyObject(ListMetricsOptions.class)))
.andReturn(response1) .andReturn(response1)
.once(); .once();
expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class))) expect(metricClient.list(anyObject(ListMetricsOptions.class)))
.andReturn(response2) .andReturn(response2)
.once(); .once();
@ -126,7 +126,7 @@ public class CloudWatchTest {
.atLeastOnce(); .atLeastOnce();
for (List<MetricDatum> slice : Iterables.partition(metrics, 10)) { for (List<MetricDatum> slice : Iterables.partition(metrics, 10)) {
metricClient.putMetricData(slice, namespace); metricClient.putMetricsInNamespace(slice, namespace);
} }
EasyMock.replay(client, metricClient); EasyMock.replay(client, metricClient);

View File

@ -18,7 +18,12 @@
*/ */
package org.jclouds.cloudwatch.features; package org.jclouds.cloudwatch.features;
import com.google.common.collect.ImmutableMultimap; import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Date;
import java.util.TimeZone;
import org.jclouds.cloudwatch.CloudWatchClient; import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.cloudwatch.domain.Dimension; import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants; import org.jclouds.cloudwatch.domain.EC2Constants;
@ -34,11 +39,7 @@ import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.net.URI; import com.google.common.collect.ImmutableMultimap;
import java.util.Date;
import java.util.TimeZone;
import static org.testng.Assert.assertEquals;
/** /**
* @author Jeremy Whitlock, Adrian Cole * @author Jeremy Whitlock, Adrian Cole
@ -76,9 +77,8 @@ public class MetricClientExpectTest extends BaseCloudWatchClientExpectTest {
CloudWatchClient clientWhenMetricsExist = requestSendsResponse( CloudWatchClient clientWhenMetricsExist = requestSendsResponse(
listMetrics, listMetricsResponse); listMetrics, listMetricsResponse);
assertEquals(clientWhenMetricsExist.getMetricClientForRegion(null).listMetrics().toString(), assertEquals(clientWhenMetricsExist.getMetricClientForRegion(null).list().toString(),
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, " + "PaginatedSet{contents=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], marker=null}");
"dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
} }
// TODO: this should really be an empty set // TODO: this should really be an empty set
@ -90,7 +90,7 @@ public class MetricClientExpectTest extends BaseCloudWatchClientExpectTest {
CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse( CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse(
listMetrics, listMetricsResponse); listMetrics, listMetricsResponse);
clientWhenMetricsDontExist.getMetricClientForRegion(null).listMetrics(); clientWhenMetricsDontExist.getMetricClientForRegion(null).list();
} }
public void testListMetricsWithOptionsWhenResponseIs2xx() throws Exception { public void testListMetricsWithOptionsWhenResponseIs2xx() throws Exception {
@ -124,16 +124,14 @@ public class MetricClientExpectTest extends BaseCloudWatchClientExpectTest {
listMetricsWithOptionsResponse); listMetricsWithOptionsResponse);
assertEquals( assertEquals(
clientWhenMetricsWithOptionsExist.getMetricClientForRegion(null).listMetrics( clientWhenMetricsWithOptionsExist.getMetricClientForRegion(null).list(
ListMetricsOptions.builder() ListMetricsOptions.Builder
.dimension(new Dimension(EC2Constants.Dimension.INSTANCE_ID, .dimension(new Dimension(EC2Constants.Dimension.INSTANCE_ID,
"SOMEINSTANCEID")) "SOMEINSTANCEID"))
.metricName(EC2Constants.MetricName.CPU_UTILIZATION) .metricName(EC2Constants.MetricName.CPU_UTILIZATION)
.namespace("SOMENEXTTOKEN") .namespace("SOMENEXTTOKEN")
.nextToken( Namespaces.EC2) .nextMarker(Namespaces.EC2)).toString(),
.build()).toString(), "PaginatedSet{contents=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], marker=null}");
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, " +
"dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
} }
GetMetricStatistics stats = GetMetricStatistics.builder() GetMetricStatistics stats = GetMetricStatistics.builder()

View File

@ -31,7 +31,6 @@ import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants; import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatistics; import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse; import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.MetricDatum; import org.jclouds.cloudwatch.domain.MetricDatum;
import org.jclouds.cloudwatch.domain.Namespaces; import org.jclouds.cloudwatch.domain.Namespaces;
@ -40,6 +39,7 @@ import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit; import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchClientLiveTest; import org.jclouds.cloudwatch.internal.BaseCloudWatchClientLiveTest;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -84,15 +84,14 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
.value(10.0) .value(10.0)
.build(); .build();
client().putMetricData(ImmutableSet.of(metricDatum, metricDatum2), namespace); client().putMetricsInNamespace(ImmutableSet.of(metricDatum, metricDatum2), namespace);
ListMetricsOptions lmo = ListMetricsOptions.builder().namespace(namespace) ListMetricsOptions lmo = ListMetricsOptions.Builder.namespace(namespace)
.dimension(new Dimension("BaseMetricName", metricName)) .dimension(new Dimension("BaseMetricName", metricName));
.build();
boolean success = new RetryablePredicate<ListMetricsOptions>(new Predicate<ListMetricsOptions>() { boolean success = new RetryablePredicate<ListMetricsOptions>(new Predicate<ListMetricsOptions>() {
@Override @Override
public boolean apply(ListMetricsOptions options) { public boolean apply(ListMetricsOptions options) {
return Iterables.size(client().listMetrics(options)) == 2; return Iterables.size(client().list(options)) == 2;
} }
}, 20, 1, TimeUnit.MINUTES).apply(lmo); }, 20, 1, TimeUnit.MINUTES).apply(lmo);
@ -100,7 +99,7 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
Assert.fail("Unable to gather the created CloudWatch data within the time (20m) allotted."); Assert.fail("Unable to gather the created CloudWatch data within the time (20m) allotted.");
} }
ListMetricsResponse lmr = client().listMetrics(lmo); PaginatedSet<Metric> lmr = client().list(lmo);
Date endTime = new Date(metricTimestampInCloudWatch.getTime() + (60 * 1000)); // Pad a minute just in case Date endTime = new Date(metricTimestampInCloudWatch.getTime() + (60 * 1000)); // Pad a minute just in case
Date startTime = new Date(metricTimestampInCloudWatch.getTime() - (60 * 1000)); // Pad a minute just in case Date startTime = new Date(metricTimestampInCloudWatch.getTime() - (60 * 1000)); // Pad a minute just in case
@ -146,7 +145,7 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
// TODO: change this test to retrieve pre-seeded custom metrics // TODO: change this test to retrieve pre-seeded custom metrics
@Test @Test
protected void testGetMetricStatistics() { protected void testGetMetricStatistics() {
ListMetricsResponse metricsResponse = client().listMetrics(); PaginatedSet<Metric> metricsResponse = client().list();
// Walk through all datapoints in all metrics until we find a metric datapoint that returns statistics // Walk through all datapoints in all metrics until we find a metric datapoint that returns statistics
if (metricsResponse.size() > 0) { if (metricsResponse.size() > 0) {
@ -196,14 +195,14 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
@Test @Test
protected void testListMetrics() { protected void testListMetrics() {
ListMetricsResponse response; PaginatedSet<Metric> response;
String testNamespace = Namespaces.EC2; String testNamespace = Namespaces.EC2;
String testMetricName = EC2Constants.MetricName.CPU_UTILIZATION; String testMetricName = EC2Constants.MetricName.CPU_UTILIZATION;
String testDimensionName = EC2Constants.Dimension.INSTANCE_TYPE; String testDimensionName = EC2Constants.Dimension.INSTANCE_TYPE;
String testDimensionValue = "t1.micro"; String testDimensionValue = "t1.micro";
// Test an empty request (pulls all stored metric options across all products) // Test an empty request (pulls all stored metric options across all products)
response = client().listMetrics(); response = client().list();
performDefaultMetricsTests(response); performDefaultMetricsTests(response);
@ -237,12 +236,12 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
} }
// Test with a NextToken, even if it's null // Test with a NextToken, even if it's null
response = client().listMetrics(ListMetricsOptions.builder().nextToken(response.getNextToken()).build()); response = client().list(ListMetricsOptions.Builder.nextMarker(response.getNextMarker()));
performDefaultMetricsTests(response); performDefaultMetricsTests(response);
// Test with a Namespace // Test with a Namespace
response = client().listMetrics(ListMetricsOptions.builder().namespace(testNamespace).build()); response = client().list(ListMetricsOptions.Builder.namespace(testNamespace));
performDefaultMetricsTests(response); performDefaultMetricsTests(response);
@ -252,7 +251,7 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
} }
// Test with a MetricName // Test with a MetricName
response = client().listMetrics(ListMetricsOptions.builder().metricName(testMetricName).build()); response = client().list(ListMetricsOptions.Builder.metricName(testMetricName));
performDefaultMetricsTests(response); performDefaultMetricsTests(response);
@ -265,7 +264,7 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
if (testDimensionName != null) { if (testDimensionName != null) {
Dimension testDimension = new Dimension(testDimensionName, testDimensionValue); Dimension testDimension = new Dimension(testDimensionName, testDimensionValue);
response = client().listMetrics(ListMetricsOptions.builder().dimension(testDimension).build()); response = client().list(ListMetricsOptions.Builder.dimension(testDimension));
performDefaultMetricsTests(response); performDefaultMetricsTests(response);
@ -282,10 +281,10 @@ public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
} }
} }
private void performDefaultMetricsTests(ListMetricsResponse response) { private void performDefaultMetricsTests(PaginatedSet<Metric> response) {
// If there are less than 500 metrics, NextToken should be null // If there are less than 500 metrics, NextToken should be null
if (response.size() < 500) { if (response.size() < 500) {
checkArgument(response.getNextToken() == null, checkArgument(response.getNextMarker() == null,
"NextToken should be null for response with fewer than 500 metrics."); "NextToken should be null for response with fewer than 500 metrics.");
} }