modernized cloudwatch

This commit is contained in:
Adrian Cole 2012-05-01 10:11:01 -07:00
parent aa14f5b051
commit 2d8f5ec807
24 changed files with 1162 additions and 497 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.cloudwatch;
import com.google.common.collect.AbstractIterator; import com.google.common.collect.AbstractIterator;
import org.jclouds.cloudwatch.domain.ListMetricsResponse; import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import java.util.Iterator; import java.util.Iterator;
@ -41,15 +42,16 @@ public class CloudWatch {
* *
* @return iterable of metrics fitting the criteria * @return iterable of metrics fitting the criteria
*/ */
public static Iterable<Metric> listMetrics(final CloudWatchClient cloudWatchClient, public static Iterable<Metric> listMetrics(CloudWatchClient cloudWatchClient, String region,
final String region, final ListMetricsOptions options) { final ListMetricsOptions options) {
final MetricClient metricClientForRegion = cloudWatchClient.getMetricClientForRegion(region);
return new Iterable<Metric>() { return new Iterable<Metric>() {
public Iterator<Metric> iterator() { public Iterator<Metric> iterator() {
return new AbstractIterator<Metric>() { return new AbstractIterator<Metric>() {
private ListMetricsOptions lastOptions = options; private ListMetricsOptions lastOptions = options;
private ListMetricsResponse response = cloudWatchClient.listMetrics(region, lastOptions); private ListMetricsResponse response = metricClientForRegion.listMetrics(lastOptions);
private Iterator<Metric> iterator = response.getMetrics().iterator(); private Iterator<Metric> iterator = response.iterator();
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -64,8 +66,8 @@ public class CloudWatch {
.namespace(lastOptions.getNamespace()) .namespace(lastOptions.getNamespace())
.nextToken(response.getNextToken()) .nextToken(response.getNextToken())
.build(); .build();
response = cloudWatchClient.listMetrics(region, lastOptions); response = metricClientForRegion.listMetrics(lastOptions);
iterator = response.getMetrics().iterator(); iterator = response.iterator();
} }
if (iterator.hasNext()) { if (iterator.hasNext()) {
return iterator.next(); return iterator.next();

View File

@ -73,7 +73,7 @@ public class CloudWatchApiMetadata extends BaseRestApiMetadata {
.name("Amazon CloudWatch Api") .name("Amazon CloudWatch Api")
.identityName("Access Key ID") .identityName("Access Key ID")
.credentialName("Secret Access Key") .credentialName("Secret Access Key")
.version(CloudWatchAsyncClient.VERSION) .version("2010-08-01")
.documentation(URI.create("http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/")) .documentation(URI.create("http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/"))
.defaultEndpoint("https://monitoring.us-east-1.amazonaws.com") .defaultEndpoint("https://monitoring.us-east-1.amazonaws.com")
.defaultProperties(CloudWatchApiMetadata.defaultProperties()) .defaultProperties(CloudWatchApiMetadata.defaultProperties())

View File

@ -18,21 +18,24 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import com.google.common.util.concurrent.ListenableFuture; import java.util.Date;
import java.util.Set;
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.domain.Datapoint; import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Statistics; import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.features.MetricAsyncClient;
import org.jclouds.cloudwatch.functions.ISO8601Format; import org.jclouds.cloudwatch.functions.ISO8601Format;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions; import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler; import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandlerV2;
import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.ParamParser;
@ -40,28 +43,31 @@ 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 com.google.inject.Provides;
import javax.ws.rs.Path;
import java.util.Date;
import java.util.Set;
/** /**
* Provides access to Amazon CloudWatch via the Query API * Provides access to Amazon CloudWatch via the Query API
* <p/> * <p/>
* *
* @see <a * @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html" * href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequestFilters(FormSigner.class) @RequestFilters(FormSigner.class)
@VirtualHost @VirtualHost
public interface CloudWatchAsyncClient { public interface CloudWatchAsyncClient {
public static final String VERSION = "2010-08-01"; /**
*
* @return the Region codes configured
*/
@Provides
@Region
Set<String> getConfiguredRegions();
/** /**
* @see CloudWatchClient#getMetricStatisticsInRegion * @see MetricAsyncClient#getMetricStatistics
*/ */
@Deprecated @Deprecated
@POST @POST
@ -79,25 +85,9 @@ public interface CloudWatchAsyncClient {
GetMetricStatisticsOptions... options); GetMetricStatisticsOptions... options);
/** /**
* @see CloudWatchClient#listMetrics(String, org.jclouds.cloudwatch.options.ListMetricsOptions) * Provides asynchronous access to Metric features.
*/ */
@POST @Delegate
@Path("/") MetricAsyncClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
ListMetricsOptions options);
/**
* @see CloudWatchClient#getMetricStatistics(String, org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2)
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandlerV2.class)
@FormParams(keys = "Action", values = "GetMetricStatistics")
ListenableFuture<? extends GetMetricStatisticsResponse> getMetricStatistics(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
GetMetricStatisticsOptionsV2 options);
} }

View File

@ -18,31 +18,41 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.inject.Provides;
/** /**
* Provides access to Amazon CloudWatch via the Query API * Provides access to Amazon CloudWatch via the Query API
* <p/> * <p/>
* *
* @see <a * @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html" * href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface CloudWatchClient { public interface CloudWatchClient {
/**
*
* @return the Region codes configured
*/
@Provides
@Region
Set<String> getConfiguredRegions();
/** /**
* This call returns data for one or more statistics of given a metric. For more information, see * This call returns data for one or more statistics of given a metric. For more information, see
@ -80,35 +90,15 @@ public interface CloudWatchClient {
* The statistics to be returned for the given metric. ex. Average * The statistics to be returned for the given metric. ex. Average
* @param options * @param options
* more filtering options (e.g. instance ID) * more filtering options (e.g. instance ID)
* @see MetricsClient#getMetricStatistics
*/ */
@Deprecated @Deprecated
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);
/** /**
* Returns a list of valid metrics stored for the AWS account owner. * Provides synchronous access to Metric features.
*
* <p/>
* <h3>Note</h3> Up to 500 results are returned for any one call. To retrieve further results, use returned
* NextToken ({@link org.jclouds.cloudwatch.domain.ListMetricsResponse#getNextToken()})
* value with subsequent calls .To retrieve all available metrics with one call, use
* {@link CloudWatch#listMetrics(CloudWatchClient, String, org.jclouds.cloudwatch.options.ListMetricsOptions)}.
*
* @param region the region to query metrics in
* @param options the options describing the metrics query
*
* @return the response object
*/ */
ListMetricsResponse listMetrics(@Nullable String region, ListMetricsOptions options); @Delegate
MetricClient getMetricClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Gets statistics for the specified metric.
*
* @param region the region to gather metrics in
* @param options the options describing the metric statistics query
*
* @return the response object
*/
GetMetricStatisticsResponse getMetricStatistics(@Nullable String region, GetMetricStatisticsOptionsV2 options);
} }

View File

@ -0,0 +1,80 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.binders;
import javax.inject.Inject;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableMultimap;
/**
* Binds the metrics request to the http request
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html"
* />
*
* @author Jeremy Whitlock, Adrian Cole
*/
@Beta
public class GetMetricStatisticsBinder implements org.jclouds.rest.Binder {
private final DateService dateService;
@Inject
protected GetMetricStatisticsBinder(DateService dateService){
this.dateService =dateService;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
GetMetricStatistics getRequest = GetMetricStatistics.class.cast(payload);
int dimensionIndex = 1;
int statisticIndex = 1;
ImmutableMultimap.Builder<String, String> formParameters = ImmutableMultimap.<String, String> builder();
for (Dimension dimension : getRequest.getDimensions()) {
formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
formParameters.put("EndTime", dateService.iso8601SecondsDateFormat(getRequest.getEndTime()));
formParameters.put("MetricName", getRequest.getMetricName());
formParameters.put("Namespace", getRequest.getNamespace());
formParameters.put("Period", Integer.toString(getRequest.getPeriod()));
formParameters.put("StartTime", dateService.iso8601SecondsDateFormat(getRequest
.getStartTime()));
for (Statistics statistic : getRequest.getStatistics()) {
formParameters.put("Statistics.member." + statisticIndex, statistic.toString());
statisticIndex++;
}
formParameters.put("Unit", getRequest.getUnit().toString());
return ModifyRequest.putFormParams(request, formParameters.build());
}
}

View File

@ -18,11 +18,18 @@
*/ */
package org.jclouds.cloudwatch.config; package org.jclouds.cloudwatch.config;
import java.util.Map;
import org.jclouds.aws.config.FormSigningRestClientModule; import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.cloudwatch.CloudWatchAsyncClient; import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.cloudwatch.CloudWatchClient; import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.cloudwatch.features.MetricAsyncClient;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
/** /**
* Configures the Monitoring connection. * Configures the Monitoring connection.
* *
@ -30,5 +37,12 @@ import org.jclouds.rest.ConfiguresRestClient;
*/ */
@ConfiguresRestClient @ConfiguresRestClient
public class CloudWatchRestClientModule extends FormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> { public class CloudWatchRestClientModule extends FormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(MetricClient.class, MetricAsyncClient.class)
.build();
public CloudWatchRestClientModule() {
super(TypeToken.of(CloudWatchClient.class), TypeToken.of(CloudWatchAsyncClient.class), DELEGATE_MAP);
}
} }

View File

@ -24,7 +24,7 @@ import org.jclouds.javax.annotation.Nullable;
import java.util.Date; import java.util.Date;
/** /**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html?DT_Datapoint.html" * @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference?DT_Datapoint.html"
* /> * />
* *
* @author Adrian Cole * @author Adrian Cole

View File

@ -16,21 +16,17 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.cloudwatch.options; package org.jclouds.cloudwatch.domain;
import java.util.Date;
import java.util.Set;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.options.BaseHttpRequestOptions;
import org.jclouds.javax.annotation.Nullable;
import java.util.Date;
import java.util.Set;
/** /**
* Options use to get statistics for the specified metric. * Options use to get statistics for the specified metric.
@ -40,9 +36,8 @@ import java.util.Set;
* @author Jeremy Whitlock * @author Jeremy Whitlock
*/ */
@Beta @Beta
public class GetMetricStatisticsOptionsV2 extends BaseHttpRequestOptions { public class GetMetricStatistics {
private static final DateService dateService = new SimpleDateFormatDateService();
private final Set<Dimension> dimensions; private final Set<Dimension> dimensions;
private final Date endTime; private final Date endTime;
private final String metricName; private final String metricName;
@ -55,7 +50,7 @@ public class GetMetricStatisticsOptionsV2 extends BaseHttpRequestOptions {
/** /**
* Private constructor to enforce using {@link Builder}. * Private constructor to enforce using {@link Builder}.
*/ */
private GetMetricStatisticsOptionsV2(@Nullable Set<Dimension> dimensions, Date endTime, String metricName, private GetMetricStatistics(@Nullable Set<Dimension> dimensions, Date endTime, String metricName,
String namespace, int period, Date startTime, Set<Statistics> statistics, String namespace, int period, Date startTime, Set<Statistics> statistics,
Unit unit) { Unit unit) {
this.dimensions = dimensions; this.dimensions = dimensions;
@ -330,7 +325,7 @@ public class GetMetricStatisticsOptionsV2 extends BaseHttpRequestOptions {
* @throws NullPointerException if any of the required fields are null * @throws NullPointerException if any of the required fields are null
* @throws IllegalArgumentException if any of the provided fields don't meet required criteria * @throws IllegalArgumentException if any of the provided fields don't meet required criteria
*/ */
public GetMetricStatisticsOptionsV2 build() { public GetMetricStatistics build() {
Preconditions.checkNotNull(endTime, "endTime cannot be null."); Preconditions.checkNotNull(endTime, "endTime cannot be null.");
Preconditions.checkNotNull(metricName, "metricName cannot be null."); Preconditions.checkNotNull(metricName, "metricName cannot be null.");
Preconditions.checkNotNull(namespace, "namespace cannot be null."); Preconditions.checkNotNull(namespace, "namespace cannot be null.");
@ -340,34 +335,8 @@ public class GetMetricStatisticsOptionsV2 extends BaseHttpRequestOptions {
Preconditions.checkNotNull(unit, "unit cannot be null."); Preconditions.checkNotNull(unit, "unit cannot be null.");
Preconditions.checkArgument(statistics.size() >= 1, "statistics must have at least one member"); Preconditions.checkArgument(statistics.size() >= 1, "statistics must have at least one member");
GetMetricStatisticsOptionsV2 options = new GetMetricStatisticsOptionsV2(dimensions, endTime, metricName, return new GetMetricStatistics(dimensions, endTime, metricName,namespace, period, startTime, statistics, unit);
namespace, period, startTime,
statistics, unit);
int dimensionIndex = 1;
int statisticIndex = 1;
for (Dimension dimension : dimensions) {
options.formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
options.formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
} }
options.formParameters.put("EndTime", dateService.iso8601SecondsDateFormat(endTime));
options.formParameters.put("MetricName", metricName);
options.formParameters.put("Namespace", namespace);
options.formParameters.put("Period", Integer.toString(period));
options.formParameters.put("StartTime", dateService.iso8601SecondsDateFormat(startTime));
for (Statistics statistic : statistics) {
options.formParameters.put("Statistics.member." + statisticIndex, statistic.toString());
statisticIndex++;
}
options.formParameters.put("Unit", unit.toString());
return options;
}
} }
} }

View File

@ -18,38 +18,36 @@
*/ */
package org.jclouds.cloudwatch.domain; package org.jclouds.cloudwatch.domain;
import com.google.common.base.Objects;
import com.google.common.collect.Sets;
import org.jclouds.javax.annotation.Nullable;
import java.util.Set; import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
/** /**
* the list of {@link Datapoint} for the metric
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" /> * @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html" />
* *
* @author Jeremy Whitlock * @author Jeremy Whitlock
*/ */
public class GetMetricStatisticsResponse { public class GetMetricStatisticsResponse extends ForwardingSet<Datapoint> {
private final Set<Datapoint> datapoints; private final Set<Datapoint> datapoints;
private final String label; private final String label;
public GetMetricStatisticsResponse(@Nullable Set<Datapoint> datapoints, String label) { public GetMetricStatisticsResponse(@Nullable Set<Datapoint> datapoints, String label) {
// Default to an empty set
if (datapoints == null) { if (datapoints == null) {
this.datapoints = Sets.newLinkedHashSet(); this.datapoints = ImmutableSet.<Datapoint>of();
} else { } else {
this.datapoints = datapoints; this.datapoints = ImmutableSet.<Datapoint>copyOf(datapoints);
} }
this.label = label; this.label = label;
} }
/**
* return the list of {@link Datapoint} for the metric
*/
public Set<Datapoint> getDatapoints() {
return datapoints;
}
/** /**
* return the label describing the specified metric * return the label describing the specified metric
*/ */
@ -91,4 +89,9 @@ public class GetMetricStatisticsResponse {
.add("datapoints", datapoints).toString(); .add("datapoints", datapoints).toString();
} }
@Override
protected Set<Datapoint> delegate() {
return datapoints;
}
} }

View File

@ -18,18 +18,21 @@
*/ */
package org.jclouds.cloudwatch.domain; package org.jclouds.cloudwatch.domain;
import com.google.common.base.Objects;
import com.google.common.collect.Sets;
import org.jclouds.javax.annotation.Nullable;
import java.util.Set; import java.util.Set;
import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.ImmutableSet;
/** /**
* list of {@link Metric}
* @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 ListMetricsResponse { public class ListMetricsResponse extends ForwardingSet<Metric>{
private final Set<Metric> metrics; private final Set<Metric> metrics;
private final String nextToken; private final String nextToken;
@ -37,20 +40,13 @@ public class ListMetricsResponse {
public ListMetricsResponse(@Nullable Set<Metric> metrics, @Nullable String nextToken) { public ListMetricsResponse(@Nullable Set<Metric> metrics, @Nullable String nextToken) {
// Default to an empty set // Default to an empty set
if (metrics == null) { if (metrics == null) {
this.metrics = Sets.newLinkedHashSet(); this.metrics = ImmutableSet.<Metric>of();
} else { } else {
this.metrics = metrics; this.metrics = ImmutableSet.<Metric>copyOf(metrics);
} }
this.nextToken = nextToken; this.nextToken = nextToken;
} }
/**
* return the list of {@link Metric}
*/
public Set<Metric> getMetrics() {
return metrics;
}
/** /**
* return the next token or null if there is none. * return the next token or null if there is none.
*/ */
@ -93,4 +89,9 @@ public class ListMetricsResponse {
.add("nextToken", nextToken).toString(); .add("nextToken", nextToken).toString();
} }
@Override
protected Set<Metric> delegate() {
return metrics;
}
} }

View File

@ -0,0 +1,91 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.cloudwatch.binders.GetMetricStatisticsBinder;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandlerV2;
import org.jclouds.cloudwatch.xml.ListMetricsResponseHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference" />
* @author Jeremy Whitlock
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface MetricAsyncClient {
/**
* @see MetricClient#listMetrics()
*/
@POST
@Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics();
/**
* @see MetricClient#listMetrics(ListMetricsOptions)
*/
@POST
@Path("/")
@XMLResponseParser(ListMetricsResponseHandler.class)
@FormParams(keys = "Action", values = "ListMetrics")
ListenableFuture<? extends ListMetricsResponse> listMetrics(ListMetricsOptions options);
/**
* @see MetricClient#getMetricStatistics(GetMetricStatistics)
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandlerV2.class)
@FormParams(keys = "Action", values = "GetMetricStatistics")
ListenableFuture<? extends GetMetricStatisticsResponse> getMetricStatistics(
@BinderParam(GetMetricStatisticsBinder.class) GetMetricStatistics statistics);
/**
* @see MetricClient#getMetricStatistics(GetMetricStatistics, GetMetricStatisticsOptions)
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandlerV2.class)
@FormParams(keys = "Action", values = "GetMetricStatistics")
ListenableFuture<? extends GetMetricStatisticsResponse> getMetricStatistics(
@BinderParam(GetMetricStatisticsBinder.class) GetMetricStatistics statistics,
GetMetricStatisticsOptions options);
}

View File

@ -0,0 +1,73 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference" />
* @author Jeremy Whitlock
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface MetricClient {
/**
* Returns a list of valid metrics stored for the AWS account owner.
*
* <p/>
* <h3>Note</h3> Up to 500 results are returned for any one call. To retrieve further results,
* use returned NextToken (
* {@link org.jclouds.cloudwatch.domain.ListMetricsResponse#getNextToken()}) value with
* subsequent calls .To retrieve all available metrics with one call, use
* {@link #list(MetricsClient, String, org.jclouds.cloudwatch.options.ListMetricsOptions)}.
*
* @param options
* the options describing the metrics query
*
* @return the response object
*/
ListMetricsResponse listMetrics(ListMetricsOptions options);
ListMetricsResponse listMetrics();
/**
* Gets statistics for the specified metric.
*
* @param statistics
* the statistics to gather
* @param options
* the options describing the metric statistics query
*
* @return the response object
*/
GetMetricStatisticsResponse getMetricStatistics(GetMetricStatistics statistics, GetMetricStatisticsOptions options);
GetMetricStatisticsResponse getMetricStatistics(GetMetricStatistics statistics);
}

View File

@ -18,11 +18,19 @@
*/ */
package org.jclouds.cloudwatch.options; package org.jclouds.cloudwatch.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.aws.util.AWSUtils; import org.jclouds.aws.util.AWSUtils;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.Unit; import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.BaseHttpRequestOptions;
import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
/** /**
* Options used to control metric statistics are returned * Options used to control metric statistics are returned
@ -30,12 +38,45 @@ import static com.google.common.base.Preconditions.checkNotNull;
* @see <a * @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/index.html?API_GetMetricStatistics.html" * href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/index.html?API_GetMetricStatistics.html"
* /> * />
* @author Andrei Savu * @author Andrei Savu, Jeremy Whitlock
*/ */
@Deprecated
public class GetMetricStatisticsOptions extends BaseHttpRequestOptions { public class GetMetricStatisticsOptions extends BaseHttpRequestOptions {
public static final GetMetricStatisticsOptions NONE = new GetMetricStatisticsOptions(); private Set<Dimension> dimensions = Sets.newLinkedHashSet();
/**
* A dimension describing qualities of the metric. (Can be called multiple times up to a maximum of 10 times.)
*
* @param dimension the dimension describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if the number of dimensions would be greater than 10 after adding
*/
public GetMetricStatisticsOptions dimension(Dimension dimension) {
if (dimension != null) {
Preconditions.checkArgument(dimensions.size() < 10, "dimension member maximum count of 10 exceeded.");
this.dimensions.add(dimension);
}
return this;
}
/**
* A list of dimensions describing qualities of the metric. (Set can be 10 or less items.)
*
* @param dimensions the dimensions describing the qualities of the metric
*
* @return this {@code Builder} object
*
* @throws IllegalArgumentException if this is invoked more than 10 times
*/
public GetMetricStatisticsOptions dimensions(Set<Dimension> dimensions) {
if (dimensions != null) {
Preconditions.checkArgument(dimensions.size() <= 10, "dimensions can have 10 or fewer members.");
this.dimensions = ImmutableSet.<Dimension>copyOf(dimensions);
}
return this;
}
/** /**
* @param instanceId * @param instanceId
@ -75,6 +116,33 @@ public class GetMetricStatisticsOptions extends BaseHttpRequestOptions {
return options.unit(unit); return options.unit(unit);
} }
/**
* @see GetMetricStatisticsOptions#dimension
*/
public static GetMetricStatisticsOptions dimension(Dimension dimension) {
GetMetricStatisticsOptions options = new GetMetricStatisticsOptions();
return options.dimension(dimension);
}
/**
* @see GetMetricStatisticsOptions#dimensions
*/
public static GetMetricStatisticsOptions dimensions(Set<Dimension> dimensions) {
GetMetricStatisticsOptions options = new GetMetricStatisticsOptions();
return options.dimensions(dimensions);
}
}
@Override
public Multimap<String, String> buildFormParameters() {
Multimap<String, String> formParameters = super.buildFormParameters();
int dimensionIndex = 1;
for (Dimension dimension : dimensions) {
formParameters.put("Dimensions.member." + dimensionIndex + ".Name", dimension.getName());
formParameters.put("Dimensions.member." + dimensionIndex + ".Value", dimension.getValue());
dimensionIndex++;
}
return formParameters;
} }
} }

View File

@ -18,23 +18,24 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import com.google.common.base.Supplier; import static com.google.common.collect.Maps.transformValues;
import com.google.common.collect.ImmutableMap; import static org.testng.Assert.assertEquals;
import com.google.inject.Module;
import com.google.inject.TypeLiteral; import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import javax.inject.Named;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.apis.ApiMetadata; import org.jclouds.apis.ApiMetadata;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.cloudwatch.config.CloudWatchRestClientModule; import org.jclouds.cloudwatch.config.CloudWatchRestClientModule;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics; import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions; import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler; import org.jclouds.cloudwatch.xml.GetMetricStatisticsResponseHandler;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
@ -47,16 +48,10 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Suppliers2; import org.jclouds.util.Suppliers2;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import javax.inject.Named; import com.google.common.base.Supplier;
import java.io.IOException; import com.google.common.collect.ImmutableMap;
import java.lang.reflect.Method; import com.google.inject.Module;
import java.net.URI; import com.google.inject.TypeLiteral;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;
import static com.google.common.collect.Maps.transformValues;
import static org.testng.Assert.assertEquals;
/** /**
* Tests behavior of {@code CloudWatchAsyncClient} * Tests behavior of {@code CloudWatchAsyncClient}
@ -66,128 +61,9 @@ import static org.testng.Assert.assertEquals;
// NOTE:without testName, this will not call @Before* and fail w/NPE during // NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire // surefire
@Test(groups = "unit", testName = "CloudWatchAsyncClientTest") @Test(groups = "unit", testName = "CloudWatchAsyncClientTest")
@Deprecated
public class CloudWatchAsyncClientTest extends BaseAsyncClientTest<CloudWatchAsyncClient> { public class CloudWatchAsyncClientTest extends BaseAsyncClientTest<CloudWatchAsyncClient> {
/**
* Tests that {@link CloudWatchAsyncClient#getMetricStatistics(String, org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2)}
* works as expected.
*
* @throws Exception if anything goes wrong
*/
public void testGetMetricStatisticsV2() throws Exception {
Dimension dimension1 = new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID");
Dimension dimension2 = new Dimension(EC2Constants.Dimension.INSTANCE_TYPE, "t1.micro");
Date endTime = new Date(10000000l);
String metricName = EC2Constants.MetricName.CPU_UTILIZATION;
String namespace = Namespaces.EC2;
int period = 60;
Date startTime = new Date(10000000l);
Statistics statistic1 = Statistics.MAXIMUM;
Statistics statistic2 = Statistics.MINIMUM;
Unit unit = Unit.PERCENT;
GetMetricStatisticsOptionsV2 goodOptions = GetMetricStatisticsOptionsV2.builder()
.dimension(dimension1)
.dimension(dimension2)
.endTime(endTime)
.metricName(metricName)
.namespace(namespace)
.period(period)
.startTime(startTime)
.statistic(statistic1)
.statistic(statistic2)
.unit(unit).build();
Method method = CloudWatchAsyncClient.class.getMethod("getMetricStatistics", String.class,
GetMetricStatisticsOptionsV2.class);
HttpRequest request = processor.createRequest(method, null, goodOptions);
assertRequestLineEquals(request, "POST https://monitoring.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: monitoring.us-east-1.amazonaws.com\n");
// Note: Order of request params is alphabetical
assertPayloadEquals(request,
"Action=GetMetricStatistics" +
"&Dimensions.member.1.Name=" + dimension1.getName() +
"&Dimensions.member.1.Value=" + dimension1.getValue() +
"&Dimensions.member.2.Name=" + dimension2.getName() +
"&Dimensions.member.2.Value=" + dimension2.getValue() +
"&EndTime=1970-01-01T02%3A46%3A40Z" +
"&MetricName=" + metricName +
"&Namespace=" + URLEncoder.encode(namespace, "UTF-8") +
"&Period=" + period +
"&StartTime=1970-01-01T02%3A46%3A40Z" +
"&Statistics.member.1=" + statistic1 +
"&Statistics.member.2=" + statistic2 +
"&Unit=" + unit,
"application/x-www-form-urlencoded", false);
}
/**
* Tests that {@link CloudWatchAsyncClient#listMetrics(String, org.jclouds.cloudwatch.options.ListMetricsOptions)} works
* as expected.
*
* @throws Exception if anything goes wrong
*/
public void testListMetrics() throws Exception {
Method method = CloudWatchAsyncClient.class.getMethod("listMetrics", String.class, ListMetricsOptions.class);
HttpRequest request;
// Test an empty request
request = processor.createRequest(method, null, ListMetricsOptions.builder().build());
assertRequestLineEquals(request, "POST https://monitoring.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: monitoring.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Action=ListMetrics",
"application/x-www-form-urlencoded", false);
// Note: Order of request params is as follows => Namespace, MetricName, Dimensions, NextToken
// Test a request with all (only one dimension)
Dimension dimension1 = new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID");
String metricName = EC2Constants.MetricName.CPU_UTILIZATION;
String nextToken = "SOMENEXTTOKEN";
String namespace = Namespaces.EC2;
request = processor.createRequest(method, null, ListMetricsOptions.builder()
.dimension(dimension1)
.metricName(metricName)
.namespace(namespace)
.nextToken(nextToken)
.build());
assertRequestLineEquals(request, "POST https://monitoring.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: monitoring.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Action=ListMetrics" +
"&Namespace=" + URLEncoder.encode(namespace, "UTF-8") +
"&MetricName=" + metricName +
"&Dimensions.member.1.Name=" + dimension1.getName() +
"&Dimensions.member.1.Value=" + dimension1.getValue() +
"&NextToken=" + nextToken,
"application/x-www-form-urlencoded", false);
// Test a request with multiple dimensions and no NextToken
Dimension dimension2 = new Dimension(EC2Constants.Dimension.INSTANCE_TYPE, "t1.micro");
request = processor.createRequest(method, null, ListMetricsOptions.builder()
.dimension(dimension1)
.dimension(dimension2)
.metricName(metricName)
.namespace(namespace)
.build());
assertRequestLineEquals(request, "POST https://monitoring.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: monitoring.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Action=ListMetrics" +
"&Namespace=" + URLEncoder.encode(namespace, "UTF-8") +
"&MetricName=" + metricName +
"&Dimensions.member.1.Name=" + dimension1.getName() +
"&Dimensions.member.1.Value=" + dimension1.getValue() +
"&Dimensions.member.2.Name=" + dimension2.getName() +
"&Dimensions.member.2.Value=" + dimension2.getValue(),
"application/x-www-form-urlencoded", false);
}
public void testRegisterInstancesWithMeasure() throws SecurityException, NoSuchMethodException, IOException { public void testRegisterInstancesWithMeasure() throws SecurityException, NoSuchMethodException, IOException {
Date date = new Date(10000000l); Date date = new Date(10000000l);
Method method = CloudWatchAsyncClient.class.getMethod("getMetricStatisticsInRegion", String.class, String.class, Method method = CloudWatchAsyncClient.class.getMethod("getMetricStatisticsInRegion", String.class, String.class,

View File

@ -18,38 +18,30 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import com.google.common.collect.ImmutableSet; import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.reflect.TypeToken;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptionsV2;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument; import org.jclouds.apis.BaseContextLiveTest;
import static com.google.common.base.Preconditions.checkNotNull; import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/** /**
* Tests behavior of {@code CloudWatchClient} * Tests behavior of {@code CloudWatchClient}
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", singleThreaded = true) @Test(groups = "live", testName ="CloudWatchClientLiveTest", singleThreaded = true)
@Deprecated
public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> { public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> {
public CloudWatchClientLiveTest() { public CloudWatchClientLiveTest() {
provider = "cloudwatch"; provider = "cloudwatch";
@ -64,170 +56,6 @@ public class CloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<Cl
client = context.getApi(); client = context.getApi();
} }
@Test
protected void testGetMetricStatisticsV2() {
ListMetricsResponse metricsResponse = client.listMetrics(null, ListMetricsOptions.builder().build());
// Walk through all datapoints in all metrics until we find a metric datapoint that returns statistics
if (metricsResponse.getMetrics().size() > 0) {
for (Metric metric : metricsResponse.getMetrics()) {
Set<Dimension> dimensions = metric.getDimensions();
boolean testRan = false;
for (Dimension dimension : dimensions) {
Date endTime = new Date();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -60 * 24); // 24 hours
GetMetricStatisticsOptionsV2 options =
GetMetricStatisticsOptionsV2.builder()
.dimension(dimension)
.endTime(endTime)
.metricName(metric.getMetricName())
.namespace(metric.getNamespace())
.period(300)
.startTime(cal.getTime())
.statistics(ImmutableSet.of(Statistics.MAXIMUM,
Statistics.MINIMUM))
.unit(Unit.PERCENT).build();
GetMetricStatisticsResponse response = client.getMetricStatistics(null, options);
if (response.getDatapoints().size() > 0) {
checkNotNull(response.getLabel());
for (Datapoint datapoint : response.getDatapoints()) {
checkArgument(datapoint.getAverage() == null);
checkNotNull(datapoint.getMaximum());
checkNotNull(datapoint.getMinimum());
}
testRan = true;
break;
}
}
if (testRan) {
break;
}
}
}
}
@Test
protected void testListMetrics() {
ListMetricsResponse response;
String testNamespace = Namespaces.EC2;
String testMetricName = EC2Constants.MetricName.CPU_UTILIZATION;
String testDimensionName = EC2Constants.Dimension.INSTANCE_TYPE;
String testDimensionValue = "t1.micro";
// Test an empty request (pulls all stored metric options across all products)
response = client.listMetrics(null, ListMetricsOptions.builder().build());
performDefaultMetricsTests(response);
if (response.getMetrics().size() > 0) {
Metric metric = response.getMetrics().iterator().next();
testMetricName = metric.getMetricName();
testNamespace = metric.getNamespace();
if (metric.getDimensions().size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
}
if (testDimensionName == null) {
for (Metric metric1 : response.getMetrics()) {
Set<Dimension> dimensions = metric1.getDimensions();
if (dimensions.size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
break;
}
}
}
}
// Test with a NextToken, even if it's null
response = client.listMetrics(null, ListMetricsOptions.builder().nextToken(response.getNextToken()).build());
performDefaultMetricsTests(response);
// Test with a Namespace
response = client.listMetrics(null, ListMetricsOptions.builder().namespace(testNamespace).build());
performDefaultMetricsTests(response);
for (Metric metric : response.getMetrics()) {
checkArgument(metric.getNamespace().equals(testNamespace),
"All metrics should have the " + testNamespace + " Namespace.");
}
// Test with a MetricName
response = client.listMetrics(null, ListMetricsOptions.builder().metricName(testMetricName).build());
performDefaultMetricsTests(response);
for (Metric metric : response.getMetrics()) {
checkArgument(metric.getMetricName().equals(testMetricName),
"All metrics should have the " + testMetricName + " MetricName.");
}
// Test with a Dimension
if (testDimensionName != null) {
Dimension testDimension = new Dimension(testDimensionName, testDimensionValue);
response = client.listMetrics(null, ListMetricsOptions.builder().dimension(testDimension).build());
performDefaultMetricsTests(response);
for (Metric metric : response.getMetrics()) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() == 1, "There should only be one Dimension.");
Dimension dimension = dimensions.iterator().next();
checkArgument(dimension.equals(testDimension),
"The retrieved Dimension and test Dimension should be equal.");
}
}
}
private void performDefaultMetricsTests(ListMetricsResponse response) {
// If there are less than 500 metrics, NextToken should be null
if (response.getMetrics().size() < 500) {
checkArgument(response.getNextToken() == null,
"NextToken should be null for response with fewer than 500 metrics.");
}
for (Metric metric : response.getMetrics()) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() <= 10, "Dimensions set cannot be greater than 10 items.");
for (Dimension dimension : dimensions) {
checkNotNull(dimension.getName(), "Name cannot be null for a Dimension.");
checkNotNull(dimension.getValue(), "Value cannot be null for a Dimension.");
}
checkNotNull(metric.getMetricName(), "MetricName cannot be null for a Metric.");
checkNotNull(metric.getNamespace(), "Namespace cannot be null for a Metric.");
}
}
@Test
protected void testGetMetricStatisticsInRegion() {
getEC2MetricStatisticsInRegion(null);
}
protected Set<Datapoint> getEC2MetricStatisticsInRegion(String region) { protected Set<Datapoint> getEC2MetricStatisticsInRegion(String region) {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();

View File

@ -18,18 +18,20 @@
*/ */
package org.jclouds.cloudwatch; package org.jclouds.cloudwatch;
import com.google.common.collect.ImmutableSet; import static org.easymock.EasyMock.anyObject;
import com.google.common.collect.Iterables; import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import org.easymock.EasyMock; import org.easymock.EasyMock;
import org.jclouds.cloudwatch.domain.ListMetricsResponse; import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric; import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.features.MetricClient;
import org.jclouds.cloudwatch.options.ListMetricsOptions; import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.easymock.EasyMock.anyObject; import com.google.common.collect.ImmutableSet;
import static org.easymock.EasyMock.createMock; import com.google.common.collect.Iterables;
import static org.easymock.EasyMock.expect;
/** /**
* Tests behavior of {@code CloudWatch}. * Tests behavior of {@code CloudWatch}.
@ -47,14 +49,19 @@ public class CloudWatchTest {
@Test @Test
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);
ListMetricsOptions options = ListMetricsOptions.builder().build(); ListMetricsOptions options = ListMetricsOptions.builder().build();
ListMetricsResponse response = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null); ListMetricsResponse response = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null);
expect(client.listMetrics(null, options)) expect(client.getMetricClientForRegion(null))
.andReturn(metricClient)
.atLeastOnce();
expect(metricClient.listMetrics(options))
.andReturn(response) .andReturn(response)
.once(); .once();
EasyMock.replay(client); EasyMock.replay(client, metricClient);
Assert.assertEquals(1, Iterables.size(CloudWatch.listMetrics(client, null, options))); Assert.assertEquals(1, Iterables.size(CloudWatch.listMetrics(client, null, options)));
} }
@ -68,19 +75,24 @@ public class CloudWatchTest {
@Test @Test
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);
ListMetricsOptions options = ListMetricsOptions.builder().build(); ListMetricsOptions options = ListMetricsOptions.builder().build();
ListMetricsResponse response1 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), "NEXTTOKEN"); ListMetricsResponse response1 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), "NEXTTOKEN");
ListMetricsResponse response2 = new ListMetricsResponse(ImmutableSet.of(createMock(Metric.class)), null); ListMetricsResponse response2 = new ListMetricsResponse(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.listMetrics(EasyMock.eq(""), anyObject(ListMetricsOptions.class))) expect(client.getMetricClientForRegion(EasyMock.eq("")))
.andReturn(metricClient)
.atLeastOnce();
expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class)))
.andReturn(response1) .andReturn(response1)
.once(); .once();
expect(client.listMetrics(EasyMock.eq(""), anyObject(ListMetricsOptions.class))) expect(metricClient.listMetrics(anyObject(ListMetricsOptions.class)))
.andReturn(response2) .andReturn(response2)
.once(); .once();
EasyMock.replay(client); EasyMock.replay(client, metricClient);
Assert.assertEquals(2, Iterables.size(CloudWatch.listMetrics(client, "", options))); Assert.assertEquals(2, Iterables.size(CloudWatch.listMetrics(client, "", options)));
} }

View File

@ -0,0 +1,236 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unles required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either expres or implied. See the License for the
* specific language governing permisions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.Date;
import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchClientExpectTest;
import org.jclouds.cloudwatch.options.GetMetricStatisticsOptions;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
* @author Jeremy Whitlock, Adrian Cole
*/
@Test(groups = "unit", testName = "MetricClientExpectTest")
public class MetricClientExpectTest extends BaseCloudWatchClientExpectTest {
HttpRequest listMetrics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=ListMetrics").append('&')
.append("Signature=KSh9oQydCR0HMAV6QPYwDzqwQIpxs8I%2Fig7brYgHVZU%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
public void testListMetricsWhenResponseIs2xx() throws Exception {
HttpResponse listMetricsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_metrics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(
listMetrics, listMetricsResponse);
assertEquals(clientWhenMetricsExist.getMetricClientForRegion(null).listMetrics().toString(),
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListMetricsWhenResponseIs404() throws Exception {
HttpResponse listMetricsResponse = HttpResponse.builder().statusCode(404).build();
CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse(
listMetrics, listMetricsResponse);
clientWhenMetricsDontExist.getMetricClientForRegion(null).listMetrics();
}
public void testListMetricsWithOptionsWhenResponseIs2xx() throws Exception {
HttpRequest listMetricsWithOptions = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=ListMetrics").append('&')
.append("Dimensions.member.1.Name=InstanceId").append('&')
.append("Dimensions.member.1.Value=SOMEINSTANCEID").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=SOMENEXTTOKEN").append('&')
.append("NextToken=AWS%2FEC2").append('&')
.append("Signature=G05HKEx9FJpGZBk02OVYwt3u4g%2FilAY9nU5hJI9LDXA%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
HttpResponse listMetricsWithOptionsResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResourceWithContentType("/list_metrics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsWithOptionsExist = requestSendsResponse(listMetricsWithOptions,
listMetricsWithOptionsResponse);
assertEquals(
clientWhenMetricsWithOptionsExist.getMetricClientForRegion(null).listMetrics(
ListMetricsOptions.builder()
.dimension(new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID"))
.metricName(EC2Constants.MetricName.CPU_UTILIZATION)
.namespace("SOMENEXTTOKEN")
.nextToken( Namespaces.EC2)
.build()).toString(),
"ListMetricsResponse{metrics=[Metric{namespace=AWS/EC2, metricName=CPUUtilization, dimension=[Dimension{name=InstanceId, value=i-689fcf0f}]}], nextToken=null}");
}
GetMetricStatistics stats = GetMetricStatistics.builder()
.endTime(new Date(10000000l))
.metricName(EC2Constants.MetricName.CPU_UTILIZATION)
.namespace(Namespaces.EC2)
.period(60)
.startTime(new Date(10000000l))
.statistic(Statistics.MAXIMUM)
.statistic(Statistics.MINIMUM)
.unit(Unit.PERCENT).build();
HttpRequest getMetricStatistics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=GetMetricStatistics").append('&')
.append("EndTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=AWS%2FEC2").append('&')
.append("Period=60").append('&')
.append("Signature=rmg8%2Ba7w4ycy%2FKfO8rnuj6rDL0jNE96m8GKfjh3SWcw%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("StartTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("Statistics.member.1=Maximum").append('&')
.append("Statistics.member.2=Minimum").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Unit=Percent").append('&').append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
public void testGetMetricStatisticsWhenResponseIs2xx() throws Exception {
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/get_metric_statistics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
assertEquals(
clientWhenMetricsExist.getMetricClientForRegion(null).getMetricStatistics(stats).toString(),
// TODO: make an object for this
"GetMetricStatisticsResponse{label=CPUUtilization, datapoints=[Datapoint{timestamp=Thu Jan 15 16:00:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.17777777777777778, sum=null, samples=9.0, unit=Percent}, Datapoint{timestamp=Thu Jan 15 16:01:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.1, sum=null, samples=8.0, unit=Percent}]}");
}
// TODO: this should really be an empty set
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testGetMetricStatisticsWhenResponseIs404() throws Exception {
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(404).build();
CloudWatchClient clientWhenMetricsDontExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
clientWhenMetricsDontExist.getMetricClientForRegion(null).getMetricStatistics(stats);
}
public void testGetMetricStatisticsWithOptionsWhenResponseIs2xx() throws Exception {
HttpRequest getMetricStatistics = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("https://monitoring.us-east-1.amazonaws.com/"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Host", "monitoring.us-east-1.amazonaws.com")
.build())
.payload(
payloadFromStringWithContentType(
new StringBuilder()
.append("Action=GetMetricStatistics").append('&')
.append("Dimensions.member.1.Name=InstanceId").append('&')
.append("Dimensions.member.1.Value=SOMEINSTANCEID").append('&')
.append("Dimensions.member.2.Name=InstanceType").append('&')
.append("Dimensions.member.2.Value=t1.micro").append('&')
.append("EndTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("MetricName=CPUUtilization").append('&')
.append("Namespace=AWS%2FEC2").append('&')
.append("Period=60").append('&')
.append("Signature=e0WyI%2FNm4hN2%2BMEm1mjRUzsvgvMCdFXbVJWi4ORpwic%3D").append('&')
.append("SignatureMethod=HmacSHA256").append('&')
.append("SignatureVersion=2").append('&')
.append("StartTime=1970-01-01T02%3A46%3A40Z").append('&')
.append("Statistics.member.1=Maximum").append('&')
.append("Statistics.member.2=Minimum").append('&')
.append("Timestamp=2009-11-08T15%3A54%3A08.897Z").append('&')
.append("Unit=Percent").append('&')
.append("Version=2010-08-01").append('&')
.append("AWSAccessKeyId=identity").toString(), "application/x-www-form-urlencoded"))
.build();
HttpResponse getMetricStatisticsResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResourceWithContentType("/get_metric_statistics.xml", "text/xml")).build();
CloudWatchClient clientWhenMetricsExist = requestSendsResponse(getMetricStatistics, getMetricStatisticsResponse);
Dimension dimension1 = new Dimension(EC2Constants.Dimension.INSTANCE_ID, "SOMEINSTANCEID");
Dimension dimension2 = new Dimension(EC2Constants.Dimension.INSTANCE_TYPE, "t1.micro");
assertEquals(
clientWhenMetricsExist.getMetricClientForRegion(null).getMetricStatistics(stats,
GetMetricStatisticsOptions.Builder.dimension(dimension1).dimension(dimension2)).toString(),
// TODO: make an object for this
"GetMetricStatisticsResponse{label=CPUUtilization, datapoints=[Datapoint{timestamp=Thu Jan 15 16:00:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.17777777777777778, sum=null, samples=9.0, unit=Percent}, Datapoint{timestamp=Thu Jan 15 16:01:00 PST 2009, customUnit=null, maximum=null, minimum=null, average=0.1, sum=null, samples=8.0, unit=Percent}]}");
}
}

View File

@ -0,0 +1,214 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.features;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;
import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Dimension;
import org.jclouds.cloudwatch.domain.EC2Constants;
import org.jclouds.cloudwatch.domain.GetMetricStatistics;
import org.jclouds.cloudwatch.domain.GetMetricStatisticsResponse;
import org.jclouds.cloudwatch.domain.ListMetricsResponse;
import org.jclouds.cloudwatch.domain.Metric;
import org.jclouds.cloudwatch.domain.Namespaces;
import org.jclouds.cloudwatch.domain.Statistics;
import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.cloudwatch.internal.BaseCloudWatchClientLiveTest;
import org.jclouds.cloudwatch.options.ListMetricsOptions;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Jeremy Whitlock, Adrian Cole
*/
@Test(groups = "live", testName = "MetricClientLiveTest")
public class MetricClientLiveTest extends BaseCloudWatchClientLiveTest {
// TODO: change this test to retrieve pre-seeded custom metrics
@Test
protected void testGetMetricStatistics() {
ListMetricsResponse metricsResponse = client().listMetrics();
// Walk through all datapoints in all metrics until we find a metric datapoint that returns statistics
if (metricsResponse.size() > 0) {
for (Metric metric : metricsResponse) {
Set<Dimension> dimensions = metric.getDimensions();
boolean testRan = false;
for (Dimension dimension : dimensions) {
Date endTime = new Date();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -60 * 24); // 24 hours
GetMetricStatistics options =
GetMetricStatistics.builder()
.dimension(dimension)
.endTime(endTime)
.metricName(metric.getMetricName())
.namespace(metric.getNamespace())
.period(300)
.startTime(cal.getTime())
.statistics(ImmutableSet.of(Statistics.MAXIMUM,
Statistics.MINIMUM))
.unit(Unit.PERCENT).build();
GetMetricStatisticsResponse response = client().getMetricStatistics(options);
if (response.size() > 0) {
checkNotNull(response.getLabel());
for (Datapoint datapoint : response) {
checkArgument(datapoint.getAverage() == null);
checkNotNull(datapoint.getMaximum());
checkNotNull(datapoint.getMinimum());
}
testRan = true;
break;
}
}
if (testRan) {
break;
}
}
}
}
@Test
protected void testListMetrics() {
ListMetricsResponse response;
String testNamespace = Namespaces.EC2;
String testMetricName = EC2Constants.MetricName.CPU_UTILIZATION;
String testDimensionName = EC2Constants.Dimension.INSTANCE_TYPE;
String testDimensionValue = "t1.micro";
// Test an empty request (pulls all stored metric options across all products)
response = client().listMetrics();
performDefaultMetricsTests(response);
if (response.size() > 0) {
Metric metric = response.iterator().next();
testMetricName = metric.getMetricName();
testNamespace = metric.getNamespace();
if (metric.getDimensions().size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
}
if (testDimensionName == null) {
for (Metric metric1 : response) {
Set<Dimension> dimensions = metric1.getDimensions();
if (dimensions.size() > 0) {
Dimension dimension = metric.getDimensions().iterator().next();
testDimensionName = dimension.getName();
testDimensionValue = dimension.getValue();
break;
}
}
}
}
// Test with a NextToken, even if it's null
response = client().listMetrics(ListMetricsOptions.builder().nextToken(response.getNextToken()).build());
performDefaultMetricsTests(response);
// Test with a Namespace
response = client().listMetrics(ListMetricsOptions.builder().namespace(testNamespace).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
checkArgument(metric.getNamespace().equals(testNamespace),
"All metrics should have the " + testNamespace + " Namespace.");
}
// Test with a MetricName
response = client().listMetrics(ListMetricsOptions.builder().metricName(testMetricName).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
checkArgument(metric.getMetricName().equals(testMetricName),
"All metrics should have the " + testMetricName + " MetricName.");
}
// Test with a Dimension
if (testDimensionName != null) {
Dimension testDimension = new Dimension(testDimensionName, testDimensionValue);
response = client().listMetrics(ListMetricsOptions.builder().dimension(testDimension).build());
performDefaultMetricsTests(response);
for (Metric metric : response) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() == 1, "There should only be one Dimension.");
Dimension dimension = dimensions.iterator().next();
checkArgument(dimension.equals(testDimension),
"The retrieved Dimension and test Dimension should be equal.");
}
}
}
private void performDefaultMetricsTests(ListMetricsResponse response) {
// If there are less than 500 metrics, NextToken should be null
if (response.size() < 500) {
checkArgument(response.getNextToken() == null,
"NextToken should be null for response with fewer than 500 metrics.");
}
for (Metric metric : response) {
Set<Dimension> dimensions = metric.getDimensions();
checkArgument(dimensions.size() <= 10, "Dimensions set cannot be greater than 10 items.");
for (Dimension dimension : dimensions) {
checkNotNull(dimension.getName(), "Name cannot be null for a Dimension.");
checkNotNull(dimension.getValue(), "Value cannot be null for a Dimension.");
}
checkNotNull(metric.getMetricName(), "MetricName cannot be null for a Metric.");
checkNotNull(metric.getNamespace(), "Namespace cannot be null for a Metric.");
}
}
protected MetricClient client() {
return context.getApi().getMetricClientForRegion(null);
}
}

View File

@ -0,0 +1,38 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import java.util.Properties;
import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchAsyncClientExpectTest extends BaseCloudWatchExpectTest<CloudWatchAsyncClient> {
public CloudWatchAsyncClient createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return createInjector(fn, module, props).getInstance(CloudWatchAsyncClient.class);
}
}

View File

@ -0,0 +1,29 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import org.jclouds.cloudwatch.CloudWatchClient;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchClientExpectTest extends BaseCloudWatchExpectTest<CloudWatchClient> {
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.cloudwatch.CloudWatchApiMetadata;
import org.jclouds.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.cloudwatch.CloudWatchClient;
import org.jclouds.rest.RestContext;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseCloudWatchClientLiveTest extends BaseContextLiveTest<RestContext<CloudWatchClient, CloudWatchAsyncClient>> {
public BaseCloudWatchClientLiveTest() {
provider = "cloudwatch";
}
@Override
protected TypeToken<RestContext<CloudWatchClient, CloudWatchAsyncClient>> contextType() {
return CloudWatchApiMetadata.CONTEXT_TOKEN;
}
}

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.cloudwatch.internal;
import static com.google.common.collect.Maps.transformValues;
import java.net.URI;
import java.util.Map;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.cloudwatch.config.CloudWatchRestClientModule;
import org.jclouds.date.DateService;
import org.jclouds.location.config.LocationModule;
import org.jclouds.location.suppliers.RegionIdToURISupplier;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.internal.BaseRestClientExpectTest;
import org.jclouds.util.Suppliers2;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class BaseCloudWatchExpectTest<T> extends BaseRestClientExpectTest<T> {
public BaseCloudWatchExpectTest() {
provider = "cloudwatch";
}
@ConfiguresRestClient
private static final class TestMonitoringRestClientModule extends CloudWatchRestClientModule {
@Override
protected void installLocations() {
install(new LocationModule());
bind(RegionIdToURISupplier.class).toInstance(new RegionIdToURISupplier() {
@Override
public Map<String, Supplier<URI>> get() {
return transformValues(ImmutableMap.<String, URI> of(Region.EU_WEST_1, URI
.create("https://ec2.eu-west-1.amazonaws.com"), Region.US_EAST_1, URI
.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, URI
.create("https://ec2.us-west-1.amazonaws.com")), Suppliers2.<URI> ofInstanceFunction());
}
});
}
@Override
protected String provideTimeStamp(final DateService dateService,
@Named(Constants.PROPERTY_SESSION_INTERVAL) int expiration) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestMonitoringRestClientModule();
}
}

View File

@ -26,6 +26,7 @@ import java.util.Set;
import org.jclouds.cloudwatch.domain.Datapoint; import org.jclouds.cloudwatch.domain.Datapoint;
import org.jclouds.cloudwatch.domain.Unit; import org.jclouds.cloudwatch.domain.Unit;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -40,13 +41,9 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "unit", testName = "GetMetricStatisticsResponseHandlerTest") @Test(groups = "unit", testName = "GetMetricStatisticsResponseHandlerTest")
public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest { public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() { public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/get_metric_statistics.xml"); InputStream is = getClass().getResourceAsStream("/get_metric_statistics.xml");
Set<Datapoint> expected = ImmutableSet.of(new Datapoint(0.17777777777777778, null, null, dateService Set<Datapoint> expected = expected();
.iso8601SecondsDateParse("2009-01-16T00:00:00Z"), 9.0, null, Unit.PERCENT, null), new Datapoint(
0.1, null, null, dateService.iso8601SecondsDateParse("2009-01-16T00:01:00Z"), 8.0, null,
Unit.PERCENT, null));
GetMetricStatisticsResponseHandler handler = injector.getInstance(GetMetricStatisticsResponseHandler.class); GetMetricStatisticsResponseHandler handler = injector.getInstance(GetMetricStatisticsResponseHandler.class);
Set<Datapoint> result = factory.create(handler).parse(is); Set<Datapoint> result = factory.create(handler).parse(is);
@ -54,4 +51,14 @@ public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest {
assertEquals(result, expected); assertEquals(result, expected);
} }
DateService dateService = new SimpleDateFormatDateService();
public Set<Datapoint> expected() {
Set<Datapoint> expected = ImmutableSet.of(new Datapoint(0.17777777777777778, null, null, dateService
.iso8601SecondsDateParse("2009-01-16T00:00:00Z"), 9.0, null, Unit.PERCENT, null), new Datapoint(0.1,
null, null, dateService.iso8601SecondsDateParse("2009-01-16T00:01:00Z"), 8.0, null, Unit.PERCENT, null));
return expected;
}
} }

View File

@ -0,0 +1,16 @@
<ListMetricsResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
<ListMetricsResult>
<Metrics>
<member>
<Dimensions>
<member>
<Name>InstanceId</Name>
<Value>i-689fcf0f</Value>
</member>
</Dimensions>
<MetricName>CPUUtilization</MetricName>
<Namespace>AWS/EC2</Namespace>
</member>
</Metrics>
</ListMetricsResult>
</ListMetricsResponse>