Issue 334: started on cloudwatch, which is documented here: http://code.google.com/p/jclouds/wiki/EC2?#Monitoring_(Cloud_Watch)

This commit is contained in:
Adrian Cole 2010-08-16 12:35:25 -07:00
parent 6e09985659
commit df6fddb49d
37 changed files with 1331 additions and 173 deletions

View File

@ -0,0 +1,75 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.util.Date;
import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.aws.cloudwatch.functions.ISO8601Format;
import org.jclouds.aws.cloudwatch.xml.GetMetricStatisticsResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.functions.RegionToEndpoint;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
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/DeveloperGuide/index.html"
* />
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = CloudWatchAsyncClient.VERSION)
@VirtualHost
public interface CloudWatchAsyncClient {
public static final String VERSION = "2009-05-15";
/**
* @see CloudWatchClient#getMetricStatisticsInRegion
*/
@POST
@Path("/")
@XMLResponseParser(GetMetricStatisticsResponseHandler.class)
@FormParams(keys = ACTION, values = "GetMetricStatistics")
ListenableFuture<? extends Set<Datapoint>> getMetricStatisticsInRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@FormParam("MeasureName") String measureName,
@FormParam("StartTime") @ParamParser(ISO8601Format.class) Date startTime,
@FormParam("EndTime") @ParamParser(ISO8601Format.class) Date endTime, @FormParam("Period") int period,
@FormParam("Statistics.member.1") String statistics);
}

View File

@ -0,0 +1,78 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to Amazon CloudWatch via the Query API
* <p/>
*
* @see <a
* href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html"
* />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface CloudWatchClient {
/**
* This call returns data for one or more statistics of given a metric. For more information, see
* Statistic and Metric.
* <p/>
* <h3>Note</h3> The maximum number of datapoints that the Amazon CloudWatch service will return
* in a single GetMetricStatistics request is 1,440. If a request is made that would generate
* more datapoints than this amount, Amazon CloudWatch will return an error. You can alter your
* request by narrowing the time range (StartTime, EndTime) or increasing the Period in your
* single request. You may also get all of the data at the granularity you originally asked for
* by making multiple requests with adjacent time ranges.
*
* @param region
* region to gather metrics in
* @param measureName
* The measure name that corresponds to the measure for the gathered metric.
* <p/>
* note
* <p/>
* Must be a valid collected metric with the corresponding measure name, please see
* Available Amazon CloudWatch Metrics
* @param startTime
* The timestamp of the first datapoint to return, inclusive. We round your value down
* to the nearest minute. You can set your start time for more than two weeks in the
* past. However, you will only get data for the past two weeks.
* @param endTime
* The timestamp to use for determining the last datapoint to return. This is the last
* datapoint to fetch, exclusive.
* @param period
* The granularity (in seconds) of the returned datapoints.
* @param statistics
* The statistics to be returned for the given metric. ex. Average
*/
Set<Datapoint> getMetricStatisticsInRegion(@Nullable String region, String measureName, Date startTime,
Date endTime, int period, String statistics);
}

View File

@ -0,0 +1,56 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import java.util.List;
import java.util.Properties;
import org.jclouds.aws.cloudwatch.config.CloudWatchRestClientModule;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Creates {@link MonitoringContext} or {@link Injector} instances based on the most commonly requested
* arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see MonitoringContext
*/
public class CloudWatchContextBuilder extends RestContextBuilder<CloudWatchClient, CloudWatchAsyncClient> {
public CloudWatchContextBuilder(Properties props) {
super(CloudWatchClient.class, CloudWatchAsyncClient.class, props);
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new CloudWatchRestClientModule());
}
}

View File

@ -0,0 +1,70 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS;
import java.util.Properties;
import org.jclouds.PropertiesBuilder;
import org.jclouds.aws.domain.Region;
import com.google.common.base.Joiner;
/**
* Builds properties used in Cloud Watch Clients
*
* @author Adrian Cole
*/
public class CloudWatchPropertiesBuilder extends PropertiesBuilder {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
properties.setProperty(PROPERTY_API_VERSION, CloudWatchAsyncClient.VERSION);
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_EAST_1,
Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT,
"https://monitoring.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
"https://monitoring.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
"https://monitoring.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.EU_WEST_1,
"https://monitoring.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://monitoring.ap-southeast-1.amazonaws.com");
return properties;
}
public CloudWatchPropertiesBuilder() {
super();
}
public CloudWatchPropertiesBuilder(Properties properties) {
super(properties);
}
}

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.config;
import org.jclouds.aws.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.aws.cloudwatch.CloudWatchClient;
import org.jclouds.aws.config.AWSFormSigningRestClientModule;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient;
/**
* Configures the Monitoring connection.
*
* @author Adrian Cole
*/
@RequiresHttp
@ConfiguresRestClient
public class CloudWatchRestClientModule extends AWSFormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> {
public CloudWatchRestClientModule() {
super(CloudWatchClient.class, CloudWatchAsyncClient.class);
}
}

View File

@ -0,0 +1,193 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.domain;
import java.util.Date;
import javax.annotation.Nullable;
/**
* @see <a href="http://docs.amazonwebservices.com/AmazonCloudWatch/latest/DeveloperGuide/index.html?DT_Datapoint.html"
* />
*
* @author Adrian Cole
*/
public class Datapoint {
private final Double average;
private final Double maximum;
private final Double minimum;
private final Date timestamp;
private final Double samples;
private final Double sum;
private final StandardUnit unit;
private final String customUnit;
public Datapoint(@Nullable Double average, @Nullable Double maximum, @Nullable Double minimum,
@Nullable Date timestamp, @Nullable Double samples, @Nullable Double sum, @Nullable StandardUnit unit,
@Nullable String customUnit) {
this.average = average;
this.maximum = maximum;
this.minimum = minimum;
this.timestamp = timestamp;
this.samples = samples;
this.sum = sum;
this.unit = unit;
this.customUnit = customUnit;
}
/**
* return Average of samples for the datapoint.
*/
@Nullable
Double getAverage() {
return average;
}
/**
* return Maximum of the samples used for the datapoint.
*/
@Nullable
Double getMaximum() {
return maximum;
}
/**
* return Minimum of samples for the datapoint.
*/
@Nullable
Double getMinimum() {
return minimum;
}
/**
* return Indicates the beginning of the time aggregation for this value and samples.
*/
@Nullable
Date getTimestamp() {
return timestamp;
}
/**
* return The number of Measurements that contributed to the aggregate value of this datapoint.
*/
@Nullable
Double getSamples() {
return samples;
}
/**
* return Sum of samples for the datapoint.
*/
@Nullable
Double getSum() {
return sum;
}
/**
* return Standard unit used for the datapoint.
*/
@Nullable
StandardUnit getUnit() {
return unit;
}
/**
* return CustomUnit defined for the datapoint.
*/
@Nullable
String getCustomUnit() {
return customUnit;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((average == null) ? 0 : average.hashCode());
result = prime * result + ((customUnit == null) ? 0 : customUnit.hashCode());
result = prime * result + ((maximum == null) ? 0 : maximum.hashCode());
result = prime * result + ((minimum == null) ? 0 : minimum.hashCode());
result = prime * result + ((samples == null) ? 0 : samples.hashCode());
result = prime * result + ((sum == null) ? 0 : sum.hashCode());
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Datapoint other = (Datapoint) obj;
if (average == null) {
if (other.average != null)
return false;
} else if (!average.equals(other.average))
return false;
if (customUnit == null) {
if (other.customUnit != null)
return false;
} else if (!customUnit.equals(other.customUnit))
return false;
if (maximum == null) {
if (other.maximum != null)
return false;
} else if (!maximum.equals(other.maximum))
return false;
if (minimum == null) {
if (other.minimum != null)
return false;
} else if (!minimum.equals(other.minimum))
return false;
if (samples == null) {
if (other.samples != null)
return false;
} else if (!samples.equals(other.samples))
return false;
if (sum == null) {
if (other.sum != null)
return false;
} else if (!sum.equals(other.sum))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
if (unit == null) {
if (other.unit != null)
return false;
} else if (!unit.equals(other.unit))
return false;
return true;
}
@Override
public String toString() {
return "[average=" + average + ", customUnit=" + customUnit + ", maximum=" + maximum + ", minimum=" + minimum
+ ", samples=" + samples + ", sum=" + sum + ", timestamp=" + timestamp + ", unit=" + unit + "]";
}
}

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CaseFormat;
/**
*
*
* @author Adrian Cole
*/
public enum StandardUnit {
SECONDS, PERCENT, BYTES, BITS, COUNT, BITS_PER_SECOND, COUNT_PER_SECOND, NONE;
public String value() {
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name().replace("_PER_", "/")));
}
@Override
public String toString() {
return value();
}
public static StandardUnit fromValue(String state) {
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state").replace("/",
"_PER_")));
}
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.functions;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Date;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.date.DateService;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class ISO8601Format implements Function<Object, String> {
private final DateService dateService;
@Inject
ISO8601Format(DateService dateService) {
this.dateService = dateService;
}
@Override
public String apply(Object from) {
checkArgument(from instanceof Date, "this binder is only valid for Date!");
return dateService.iso8601SecondsDateFormat(Date.class.cast(from));
}
}

View File

@ -0,0 +1,98 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.xml;
import java.util.Date;
import javax.inject.Inject;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.aws.cloudwatch.domain.StandardUnit;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
/**
*
* @author Adrian Cole
*/
public class DatapointHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Datapoint> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
private Double average;
private Double maximum;
private Double minimum;
private Date timestamp;
private Double samples;
private Double sum;
private StandardUnit unit;
private String customUnit;
@Inject
public DatapointHandler(DateService dateService) {
this.dateService = dateService;
}
public Datapoint getResult() {
Datapoint datapoint = new Datapoint(average, maximum, minimum, timestamp, samples, sum, unit, customUnit);
this.average = null;
this.maximum = null;
this.minimum = null;
this.timestamp = null;
this.samples = null;
this.sum = null;
this.unit = null;
this.customUnit = null;
return datapoint;
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("Average")) {
average = doubleOrNull();
} else if (qName.equals("Maximum")) {
maximum = doubleOrNull();
} else if (qName.equals("Minimum")) {
minimum = doubleOrNull();
} else if (qName.equals("Timestamp")) {
timestamp = dateService.iso8601SecondsDateParse(currentText.toString().trim());
} else if (qName.equals("Samples")) {
samples = doubleOrNull();
} else if (qName.equals("Sum")) {
sum = doubleOrNull();
} else if (qName.equals("Unit")) {
unit = StandardUnit.fromValue(currentText.toString().trim());
} else if (qName.equals("CustomUnit")) {
customUnit = currentText.toString().trim();
}
currentText = new StringBuilder();
}
private Double doubleOrNull() {
String string = currentText.toString().trim();
if (!string.equals("")) {
return new Double(string);
}
return null;
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,67 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.xml;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
public class GetMetricStatisticsResponseHandler extends ParseSax.HandlerWithResult<Set<Datapoint>> {
private Set<Datapoint> datapoints = Sets.newLinkedHashSet();
private final DatapointHandler datapointHandler;
@Inject
public GetMetricStatisticsResponseHandler(DatapointHandler DatapointHandler) {
this.datapointHandler = DatapointHandler;
}
public Set<Datapoint> getResult() {
return datapoints;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
datapointHandler.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
datapointHandler.endElement(uri, localName, qName);
if (qName.equals("member")) {
this.datapoints.add(datapointHandler.getResult());
}
}
public void characters(char ch[], int start, int length) {
datapointHandler.characters(ch, start, length);
}
}

View File

@ -71,6 +71,8 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
eTo.noKeyPair(); eTo.noKeyPair();
if (eFrom.getSubnetId() != null) if (eFrom.getSubnetId() != null)
eTo.subnetId(eFrom.getSubnetId()); eTo.subnetId(eFrom.getSubnetId());
if (eFrom.isMonitoringEnabled())
eTo.enableMonitoring();
} }
} }

View File

@ -34,11 +34,11 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
/** /**
* Contains options supported in the {@code ComputeService#runNode} operation on * Contains options supported in the {@code ComputeService#runNode} operation on the "ec2" provider.
* the "ec2" provider. <h2> * <h2>
* Usage</h2> The recommended way to instantiate a EC2TemplateOptions object is * Usage</h2> The recommended way to instantiate a EC2TemplateOptions object is to statically import
* to statically import EC2TemplateOptions.* and invoke a static creation method * EC2TemplateOptions.* and invoke a static creation method followed by an instance mutator (if
* followed by an instance mutator (if needed): * needed):
* <p/> * <p/>
* <code> * <code>
* import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.*; * import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.*;
@ -55,6 +55,7 @@ public class EC2TemplateOptions extends TemplateOptions {
private Set<String> groupIds = ImmutableSet.of(); private Set<String> groupIds = ImmutableSet.of();
private String keyPair = null; private String keyPair = null;
private boolean noKeyPair; private boolean noKeyPair;
private boolean monitoringEnabled;
private String placementGroup = null; private String placementGroup = null;
private boolean noPlacementGroup; private boolean noPlacementGroup;
private String subnetId; private String subnetId;
@ -80,6 +81,16 @@ public class EC2TemplateOptions extends TemplateOptions {
return this; return this;
} }
/**
* Enable Cloudwatch monitoring
*
* @see CloudWatchClient
*/
public EC2TemplateOptions enableMonitoring() {
this.monitoringEnabled = true;
return this;
}
/** /**
* Specifies the keypair used to run instances with * Specifies the keypair used to run instances with
*/ */
@ -180,6 +191,14 @@ public class EC2TemplateOptions extends TemplateOptions {
return EC2TemplateOptions.class.cast(options.noPlacementGroup()); return EC2TemplateOptions.class.cast(options.noPlacementGroup());
} }
/**
* @see EC2TemplateOptions#enableMonitoring
*/
public static EC2TemplateOptions enableMonitoring() {
EC2TemplateOptions options = new EC2TemplateOptions();
return EC2TemplateOptions.class.cast(options.enableMonitoring());
}
// methods that only facilitate returning the correct object type // methods that only facilitate returning the correct object type
/** /**
* @see TemplateOptions#inboundPorts * @see TemplateOptions#inboundPorts
@ -251,10 +270,9 @@ public class EC2TemplateOptions extends TemplateOptions {
/** /**
* *
* special thing is that we do assume if you are passing groups that you have * special thing is that we do assume if you are passing groups that you have everything you need
* everything you need already defined. for example, our option inboundPorts * already defined. for example, our option inboundPorts normally creates ingress rules
* normally creates ingress rules accordingly but if we notice you've * accordingly but if we notice you've specified securityGroups, we do not mess with rules at all
* specified securityGroups, we do not mess with rules at all
* *
* @see TemplateOptions#inboundPorts * @see TemplateOptions#inboundPorts
*/ */
@ -323,16 +341,15 @@ public class EC2TemplateOptions extends TemplateOptions {
} }
/** /**
* @return groupIds the user specified to run instances with, or zero length * @return groupIds the user specified to run instances with, or zero length set to create an
* set to create an implicit group * implicit group
*/ */
public Set<String> getGroupIds() { public Set<String> getGroupIds() {
return groupIds; return groupIds;
} }
/** /**
* @return keyPair to use when running the instance or null, to generate a * @return keyPair to use when running the instance or null, to generate a keypair.
* keypair.
*/ */
public String getKeyPair() { public String getKeyPair() {
return keyPair; return keyPair;
@ -346,8 +363,7 @@ public class EC2TemplateOptions extends TemplateOptions {
} }
/** /**
* @return placementGroup to use when running the instance or null, to * @return placementGroup to use when running the instance or null, to generate a placementGroup.
* generate a placementGroup.
*/ */
public String getPlacementGroup() { public String getPlacementGroup() {
return placementGroup; return placementGroup;
@ -360,6 +376,13 @@ public class EC2TemplateOptions extends TemplateOptions {
return !noPlacementGroup; return !noPlacementGroup;
} }
/**
* @return true (default) if we are supposed to enable cloudwatch
*/
public boolean isMonitoringEnabled() {
return monitoringEnabled;
}
/** /**
* @return subnetId to use when running the instance or null. * @return subnetId to use when running the instance or null.
*/ */
@ -375,6 +398,7 @@ public class EC2TemplateOptions extends TemplateOptions {
result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode()); result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode());
result = prime * result + (noKeyPair ? 1231 : 1237); result = prime * result + (noKeyPair ? 1231 : 1237);
result = prime * result + (noPlacementGroup ? 1231 : 1237); result = prime * result + (noPlacementGroup ? 1231 : 1237);
result = prime * result + (monitoringEnabled ? 1231 : 1237);
result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode());
result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode());
return result; return result;
@ -403,6 +427,8 @@ public class EC2TemplateOptions extends TemplateOptions {
return false; return false;
if (noPlacementGroup != other.noPlacementGroup) if (noPlacementGroup != other.noPlacementGroup)
return false; return false;
if (monitoringEnabled != other.monitoringEnabled)
return false;
if (placementGroup == null) { if (placementGroup == null) {
if (other.placementGroup != null) if (other.placementGroup != null)
return false; return false;
@ -419,10 +445,10 @@ public class EC2TemplateOptions extends TemplateOptions {
@Override @Override
public String toString() { public String toString() {
return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", placementGroup=" return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", placementGroup="
+ placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", inboundPorts=" + placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", monitoringEnabled=" + monitoringEnabled
+ Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null) + ", publicKey=" + ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey=" + (privateKey != null)
+ (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port + ":" + seconds + ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null) + ", port:seconds=" + port
+ ", subnetId=" + subnetId + ", metadata/details: " + includeMetadata + "]"; + ":" + seconds + ", subnetId=" + subnetId + ", metadata/details: " + includeMetadata + "]";
} }
} }

View File

@ -36,6 +36,7 @@ import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.functions.RunningInstanceToNodeMetadata; import org.jclouds.aws.ec2.compute.functions.RunningInstanceToNodeMetadata;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.aws.ec2.options.RunInstancesOptions;
@ -114,6 +115,9 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate
RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region, RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.execute(region,
tag, template); tag, template);
if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled())
instanceOptions.enableMonitoring();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template
.getImage().getProviderId(), instanceOptions.buildFormParameters()); .getImage().getProviderId(), instanceOptions.buildFormParameters());

View File

@ -133,7 +133,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
@Nullable @Nullable
private final String keyName; private final String keyName;
private final Date launchTime; private final Date launchTime;
private final boolean monitoring; private final MonitoringState monitoringState;
private final String availabilityZone; private final String availabilityZone;
@Nullable @Nullable
private final String placementGroup; private final String placementGroup;
@ -165,7 +165,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
public RunningInstance(String region, Iterable<String> groupIds, @Nullable String amiLaunchIndex, public RunningInstance(String region, Iterable<String> groupIds, @Nullable String amiLaunchIndex,
@Nullable String dnsName, String imageId, String instanceId, InstanceState instanceState, @Nullable String dnsName, String imageId, String instanceId, InstanceState instanceState,
String instanceType, @Nullable String ipAddress, @Nullable String kernelId, @Nullable String keyName, String instanceType, @Nullable String ipAddress, @Nullable String kernelId, @Nullable String keyName,
Date launchTime, boolean monitoring, String availabilityZone, @Nullable String placementGroup, Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup,
String virtualizationType, @Nullable String platform, @Nullable String privateDnsName, String virtualizationType, @Nullable String platform, @Nullable String privateDnsName,
@Nullable String privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId, @Nullable String privateIpAddress, Set<String> productCodes, @Nullable String ramdiskId,
@Nullable String reason, @Nullable String subnetId, @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String reason, @Nullable String subnetId, @Nullable String vpcId, RootDeviceType rootDeviceType,
@ -182,7 +182,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
this.kernelId = kernelId; this.kernelId = kernelId;
this.keyName = keyName; this.keyName = keyName;
this.launchTime = checkNotNull(launchTime, "launchTime"); this.launchTime = checkNotNull(launchTime, "launchTime");
this.monitoring = checkNotNull(monitoring, "monitoring"); this.monitoringState = monitoringState;
this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone"); this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone");
this.placementGroup = placementGroup; this.placementGroup = placementGroup;
this.virtualizationType = virtualizationType; this.virtualizationType = virtualizationType;
@ -282,10 +282,10 @@ public class RunningInstance implements Comparable<RunningInstance> {
} }
/** /**
* Specifies whether monitoring is enabled for the instance. * State of monitoring for the instance.
*/ */
public boolean isMonitoring() { public MonitoringState getMonitoringState() {
return monitoring; return monitoringState;
} }
/** /**
@ -407,7 +407,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode()); result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode()); result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode()); result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode());
result = prime * result + (monitoring ? 1231 : 1237); result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode());
result = prime * result + ((platform == null) ? 0 : platform.hashCode()); result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode()); result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode());
result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode()); result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode());
@ -504,7 +504,10 @@ public class RunningInstance implements Comparable<RunningInstance> {
return false; return false;
} else if (!launchTime.equals(other.launchTime)) } else if (!launchTime.equals(other.launchTime))
return false; return false;
if (monitoring != other.monitoring) if (monitoringState == null) {
if (other.monitoringState != null)
return false;
} else if (!monitoringState.equals(other.monitoringState))
return false; return false;
if (platform == null) { if (platform == null) {
if (other.platform != null) if (other.platform != null)
@ -561,7 +564,7 @@ public class RunningInstance implements Comparable<RunningInstance> {
+ dnsName + ", ebsBlockDevices=" + ebsBlockDevices + ", groupIds=" + groupIds + ", imageId=" + imageId + dnsName + ", ebsBlockDevices=" + ebsBlockDevices + ", groupIds=" + groupIds + ", imageId=" + imageId
+ ", instanceId=" + instanceId + ", instanceState=" + instanceState + ", instanceType=" + instanceType + ", instanceId=" + instanceId + ", instanceState=" + instanceState + ", instanceType=" + instanceType
+ ", ipAddress=" + ipAddress + ", kernelId=" + kernelId + ", keyName=" + keyName + ", launchTime=" + ", ipAddress=" + ipAddress + ", kernelId=" + kernelId + ", keyName=" + keyName + ", launchTime="
+ launchTime + ", monitoring=" + monitoring + ", platform=" + platform + ", privateDnsName=" + launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName="
+ privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes + privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes
+ ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName=" + ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName="
+ rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", subnetId=" + subnetId + ", vpcId=" + vpcId + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", subnetId=" + subnetId + ", vpcId=" + vpcId

View File

@ -19,6 +19,8 @@
package org.jclouds.aws.ec2.predicates; package org.jclouds.aws.ec2.predicates;
import java.util.NoSuchElementException;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -57,12 +59,13 @@ public class InstancePresent implements Predicate<RunningInstance> {
return true; return true;
} catch (ResourceNotFoundException e) { } catch (ResourceNotFoundException e) {
return false; return false;
} catch (NoSuchElementException e) {
return false;
} }
} }
private RunningInstance refresh(RunningInstance instance) { private RunningInstance refresh(RunningInstance instance) {
return Iterables.getOnlyElement(Iterables.getOnlyElement(client return Iterables.getOnlyElement(Iterables.getOnlyElement(client.getInstanceServices().describeInstancesInRegion(
.getInstanceServices().describeInstancesInRegion( instance.getRegion(), instance.getId())));
instance.getRegion(), instance.getId())));
} }
} }

View File

@ -29,6 +29,7 @@ import javax.inject.Inject;
import org.jclouds.aws.Region; import org.jclouds.aws.Region;
import org.jclouds.aws.ec2.domain.Attachment; import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RootDeviceType; import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
@ -75,7 +76,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
private String kernelId; private String kernelId;
private String keyName; private String keyName;
private Date launchTime; private Date launchTime;
private boolean monitoring; private MonitoringState monitoringState;
private String availabilityZone; private String availabilityZone;
private String placementGroup; private String placementGroup;
private String virtualizationType = "paravirtual"; private String virtualizationType = "paravirtual";
@ -90,6 +91,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected boolean inInstances; protected boolean inInstances;
protected boolean inProductCodes; protected boolean inProductCodes;
protected boolean inGroups; protected boolean inGroups;
protected boolean inMonitoring;
private boolean inBlockDeviceMapping; private boolean inBlockDeviceMapping;
private Map<String, RunningInstance.EbsBlockDevice> ebsBlockDevices = Maps.newHashMap(); private Map<String, RunningInstance.EbsBlockDevice> ebsBlockDevices = Maps.newHashMap();
@ -111,6 +114,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
} else if (qName.equals("blockDeviceMapping")) { } else if (qName.equals("blockDeviceMapping")) {
inBlockDeviceMapping = true; inBlockDeviceMapping = true;
} }
if (qName.equals("monitoring"))
inMonitoring = true;
} }
protected String currentOrNull() { protected String currentOrNull() {
@ -155,8 +160,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
// Eucalyptus // Eucalyptus
launchTime = dateService.iso8601SecondsDateParse(currentOrNull()); launchTime = dateService.iso8601SecondsDateParse(currentOrNull());
} }
} else if (qName.equals("enabled")) { } else if (qName.equals("state") && inMonitoring) {
monitoring = Boolean.parseBoolean(currentOrNull()); monitoringState = MonitoringState.fromValue(currentOrNull());
} else if (qName.equals("availabilityZone")) { } else if (qName.equals("availabilityZone")) {
availabilityZone = currentOrNull(); availabilityZone = currentOrNull();
} else if (qName.equals("groupName")) { } else if (qName.equals("groupName")) {
@ -188,6 +193,8 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
inInstances = false; inInstances = false;
} else if (qName.equals("groupSet")) { } else if (qName.equals("groupSet")) {
inGroups = false; inGroups = false;
} else if (qName.equals("monitoring")) {
inMonitoring = false;
} else if (qName.equals("blockDeviceMapping")) { } else if (qName.equals("blockDeviceMapping")) {
inBlockDeviceMapping = false; inBlockDeviceMapping = false;
} else if (qName.equals("deviceName")) { } else if (qName.equals("deviceName")) {
@ -213,7 +220,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
protected void inItem() { protected void inItem() {
if (inBlockDeviceMapping) { if (inBlockDeviceMapping) {
ebsBlockDevices.put(deviceName, new RunningInstance.EbsBlockDevice(volumeId, attachmentStatus, attachTime, ebsBlockDevices.put(deviceName, new RunningInstance.EbsBlockDevice(volumeId, attachmentStatus, attachTime,
deleteOnTermination)); deleteOnTermination));
this.deviceName = null; this.deviceName = null;
this.volumeId = null; this.volumeId = null;
this.attachmentStatus = null; this.attachmentStatus = null;
@ -235,9 +242,9 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
if (region == null) if (region == null)
region = defaultRegion; region = defaultRegion;
instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId,
instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoring, availabilityZone, instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState,
placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress, productCodes, ramdiskId, availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress,
reason, subnetId, vpcId, rootDeviceType, rootDeviceName, ebsBlockDevices)); productCodes, ramdiskId, reason, subnetId, vpcId, rootDeviceType, rootDeviceName, ebsBlockDevices));
this.amiLaunchIndex = null; this.amiLaunchIndex = null;
this.dnsName = null; this.dnsName = null;
this.imageId = null; this.imageId = null;
@ -248,7 +255,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
this.kernelId = null; this.kernelId = null;
this.keyName = null; this.keyName = null;
this.launchTime = null; this.launchTime = null;
this.monitoring = false; this.monitoringState = null;
this.availabilityZone = null; this.availabilityZone = null;
this.placementGroup = null; this.placementGroup = null;
this.virtualizationType = "paravirtual"; this.virtualizationType = "paravirtual";
@ -275,7 +282,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
if (region == null) if (region == null)
region = defaultRegion; region = defaultRegion;
Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupIds, instances, Reservation<? extends RunningInstance> info = new Reservation<RunningInstance>(region, groupIds, instances,
ownerId, requesterId, reservationId); ownerId, requesterId, reservationId);
this.groupIds = Sets.newLinkedHashSet(); this.groupIds = Sets.newLinkedHashSet();
this.instances = Sets.newLinkedHashSet(); this.instances = Sets.newLinkedHashSet();
this.ownerId = null; this.ownerId = null;

View File

@ -29,12 +29,12 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import org.jclouds.aws.ec2.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.aws.ec2.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.elb.binders.BindAvailabilityZonesToIndexedFormParams; import org.jclouds.aws.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.aws.elb.binders.BindELBInstanceIdsToIndexedFormParams; import org.jclouds.aws.elb.binders.BindELBInstanceIdsToIndexedFormParams;
import org.jclouds.aws.elb.domain.LoadBalancer; import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.aws.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.aws.elb.xml.DescribeLoadBalancersResponseHandler; import org.jclouds.aws.elb.xml.DescribeLoadBalancersResponseHandler;
import org.jclouds.aws.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.functions.RegionToEndpoint; import org.jclouds.aws.functions.RegionToEndpoint;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.xml; package org.jclouds.aws.elb.xml;
import javax.annotation.Resource; import javax.annotation.Resource;

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.xml; package org.jclouds.aws.elb.xml;
import java.util.Set; import java.util.Set;
@ -29,37 +29,30 @@ import org.jclouds.logging.Logger;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
public class RegisterInstancesWithLoadBalancerResponseHandler extends public class RegisterInstancesWithLoadBalancerResponseHandler extends ParseSax.HandlerWithResult<Set<String>> {
ParseSax.HandlerWithResult<Set<String>> @Inject
{ public RegisterInstancesWithLoadBalancerResponseHandler() {
@Inject }
public RegisterInstancesWithLoadBalancerResponseHandler()
{
}
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private Set<String> instanceIds = Sets.newLinkedHashSet(); private Set<String> instanceIds = Sets.newLinkedHashSet();
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
public void endElement(String uri, String localName, String qName) {
if (qName.equals("InstanceId"))
instanceIds.add(currentText.toString().trim());
currentText = new StringBuilder();
}
public void endElement(String uri, String localName, String qName) @Override
{ public Set<String> getResult() {
if(qName.equals("InstanceId")) return instanceIds;
instanceIds.add(currentText.toString().trim()); }
currentText = new StringBuilder(); public void characters(char ch[], int start, int length) {
} currentText.append(ch, start, length);
@Override }
public Set<String> getResult()
{
return instanceIds;
}
public void characters(char ch[], int start, int length)
{
currentText.append(ch, start, length);
}
} }

View File

@ -71,11 +71,11 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
.getRequestLine(), response.getStatusLine()); .getRequestLine(), response.getStatusLine());
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 400: case 400:
if (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")) if (error != null && error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown"))
exception = new ResourceNotFoundException(notFoundMessage, exception); exception = new ResourceNotFoundException(notFoundMessage, exception);
else if (error.getCode().equals("IncorrectState")) else if (error != null && error.getCode().equals("IncorrectState"))
exception = new IllegalStateException(error.getMessage(), exception); exception = new IllegalStateException(error.getMessage(), exception);
else if (error.getCode().equals("AuthFailure")) else if (error != null && error.getCode().equals("AuthFailure"))
exception = new AuthorizationException(command.getRequest(), error != null ? error.getMessage() exception = new AuthorizationException(command.getRequest(), error != null ? error.getMessage()
: response.getStatusLine()); : response.getStatusLine());
break; break;

View File

@ -68,7 +68,7 @@ public class AWSUtils {
return null; return null;
// Eucalyptus and Walrus occasionally return text/plain // Eucalyptus and Walrus occasionally return text/plain
if (response.getPayload().getContentType() != null if (response.getPayload().getContentType() != null
&& response.getPayload().getContentType().indexOf("text") != -1) && response.getPayload().getContentType().indexOf("text/plain") != -1)
return null; return null;
try { try {
AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).setContext(request) AWSError error = (AWSError) factory.create(errorHandlerProvider.get()).setContext(request)

View File

@ -0,0 +1,114 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Properties;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.aws.cloudwatch.config.CloudWatchRestClientModule;
import org.jclouds.aws.cloudwatch.xml.GetMetricStatisticsResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code CloudWatchAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "cloudwatch.MonitoringAsyncClientTest")
public class CloudWatchAsyncClientTest extends RestClientTest<CloudWatchAsyncClient> {
public void testRegisterInstancesWithMeasure() throws SecurityException, NoSuchMethodException, IOException {
Date date = new Date(10000000l);
Method method = CloudWatchAsyncClient.class.getMethod("getMetricStatisticsInRegion", String.class, String.class,
Date.class, Date.class, int.class, String.class);
HttpRequest request = processor.createRequest(method, (String) null, "CPUUtilization", date, date, 60, "Average");
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,
"Version=2009-05-15&Action=GetMetricStatistics&Statistics.member.1=Average&StartTime=1970-01-01T02%3A46%3A40Z&MeasureName=CPUUtilization&EndTime=1970-01-01T02%3A46%3A40Z&Period=60",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, GetMetricStatisticsResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<CloudWatchAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<CloudWatchAsyncClient>>() {
};
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestMonitoringRestClientModule extends CloudWatchRestClientModule {
@Override
protected void configure() {
super.configure();
}
@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();
}
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("cloudwatch", "identity", "credential", new Properties());
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), FormSigner.class);
}
}

View File

@ -0,0 +1,75 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import org.jclouds.aws.domain.Region;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.inject.Module;
/**
* Tests behavior of {@code CloudWatchClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "cloudwatch.CloudWatchClientLiveTest")
public class CloudWatchClientLiveTest {
private CloudWatchClient client;
private RestContext<CloudWatchClient, CloudWatchAsyncClient> context;
@BeforeGroups(groups = { "live" })
public void setupClient() throws IOException {
String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
context = new RestContextFactory().createContext("cloudwatch", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule()));
client = context.getApi();
}
@Test
void testGetMetricStatisticsInRegion() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -1);
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
Region.AP_SOUTHEAST_1)) {
assert client.getMetricStatisticsInRegion(region, "CPUUtilization", cal.getTime(), new Date(), 60, "Average") != null;
}
}
@AfterTest
public void shutdown() {
context.close();
}
}

View File

@ -0,0 +1,57 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.cloudwatch.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.aws.cloudwatch.domain.StandardUnit;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code GetMetricStatisticsResponseHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "cloudwatch.GetMetricStatisticsResponseHandlerTest")
public class GetMetricStatisticsResponseHandlerTest extends BaseHandlerTest {
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/cloudwatch/get_metric_statistics.xml");
Set<Datapoint> expected = ImmutableSet.of(new Datapoint(0.17777777777777778, null, null, dateService
.iso8601SecondsDateParse("2009-01-16T00:00:00Z"), 9.0, null, StandardUnit.PERCENT, null), new Datapoint(
0.1, null, null, dateService.iso8601SecondsDateParse("2009-01-16T00:01:00Z"), 8.0, null,
StandardUnit.PERCENT, null));
GetMetricStatisticsResponseHandler handler = injector.getInstance(GetMetricStatisticsResponseHandler.class);
Set<Datapoint> result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
}

View File

@ -21,12 +21,17 @@ package org.jclouds.aws.ec2.compute;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.util.Date;
import java.util.Set; import java.util.Set;
import org.jclouds.aws.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.aws.cloudwatch.CloudWatchClient;
import org.jclouds.aws.cloudwatch.domain.Datapoint;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions; import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.aws.ec2.domain.SecurityGroup; import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.services.InstanceClient; import org.jclouds.aws.ec2.services.InstanceClient;
@ -40,12 +45,18 @@ import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.Module;
/** /**
* *
@ -100,8 +111,11 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
TemplateOptions options = client.templateOptions(); TemplateOptions options = client.templateOptions();
Date before = new Date();
options.as(EC2TemplateOptions.class).securityGroups(tag); options.as(EC2TemplateOptions.class).securityGroups(tag);
options.as(EC2TemplateOptions.class).keyPair(tag); options.as(EC2TemplateOptions.class).keyPair(tag);
options.as(EC2TemplateOptions.class).enableMonitoring();
String startedId = null; String startedId = null;
try { try {
@ -125,13 +139,15 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
RunningInstance instance = getInstance(instanceClient, startedId); RunningInstance instance = getInstance(instanceClient, startedId);
assertEquals(instance.getKeyName(), tag); assertEquals(instance.getKeyName(), tag);
checkMonitoringEnabled(before, instance);
// make sure we made our dummy group and also let in the user's group // make sure we made our dummy group and also let in the user's group
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag, "jclouds#" + tag)); assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet.<String> of("jclouds#" + tag + "#"
+ instance.getRegion(), tag));
// make sure our dummy group has no rules // make sure our dummy group has no rules
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
"jclouds#" + tag)); "jclouds#" + tag + "#" + instance.getRegion()));
assert group.getIpPermissions().size() == 0 : group; assert group.getIpPermissions().size() == 0 : group;
// try to run a script with the original keyPair // try to run a script with the original keyPair
@ -149,6 +165,21 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
} }
} }
private void checkMonitoringEnabled(Date before, RunningInstance instance) {
assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED);
RestContext<CloudWatchClient, CloudWatchAsyncClient> monitoringContext = new RestContextFactory().createContext(
"cloudwatch", identity, credential, ImmutableSet.<Module> of(new Log4JLoggingModule()));
try {
Set<Datapoint> datapoints = monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(),
"CPUUtilization", before, new Date(), 60, "Average");
assert datapoints != null;
} finally {
monitoringContext.close();
}
}
@Test(enabled = true, dependsOnMethods = "testDefaultTemplateBuilder") @Test(enabled = true, dependsOnMethods = "testDefaultTemplateBuilder")
public void testExtendedOptionsNoKeyPair() throws Exception { public void testExtendedOptionsNoKeyPair() throws Exception {
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())

View File

@ -21,6 +21,7 @@ package org.jclouds.aws.ec2.compute.options;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.authorizePublicKey; import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.authorizePublicKey;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.blockOnPort; import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.blockOnPort;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.enableMonitoring;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.inboundPorts; import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.inboundPorts;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.installPrivateKey; import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.installPrivateKey;
import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.keyPair; import static org.jclouds.aws.ec2.compute.options.EC2TemplateOptions.Builder.keyPair;
@ -172,6 +173,26 @@ public class EC2TemplateOptionsTest {
assert !options.shouldAutomaticallyCreateKeyPair(); assert !options.shouldAutomaticallyCreateKeyPair();
} }
@Test
public void testMonitoringEnabledDefault() {
EC2TemplateOptions options = new EC2TemplateOptions();
assert !options.isMonitoringEnabled();
}
@Test
public void testMonitoringEnabled() {
EC2TemplateOptions options = new EC2TemplateOptions();
options.enableMonitoring();
assert options.isMonitoringEnabled();
}
@Test
public void testEnableMonitoringStatic() {
EC2TemplateOptions options = enableMonitoring();
assertEquals(options.getKeyPair(), null);
assert options.isMonitoringEnabled();
}
// superclass tests // superclass tests
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Test(expectedExceptions = IllegalArgumentException.class) @Test(expectedExceptions = IllegalArgumentException.class)

View File

@ -113,10 +113,11 @@ public class EC2RunNodesAndAddToSetStrategyTest {
expect(input.template.getImage()).andReturn(input.image).atLeastOnce(); expect(input.template.getImage()).andReturn(input.image).atLeastOnce();
expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce(); expect(input.image.getProviderId()).andReturn(imageId).atLeastOnce();
expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn( expect(instanceClient.runInstancesInRegion(region, zone, imageId, 1, input.count, ec2Options)).andReturn(
(Reservation)reservation); (Reservation) reservation);
expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce(); expect(instance.getId()).andReturn(instanceCreatedId).atLeastOnce();
expect(strategy.instancePresent.apply(instance)).andReturn(true); expect(strategy.instancePresent.apply(instance)).andReturn(true);
expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); expect(input.template.getOptions()).andReturn(input.options).atLeastOnce();
expect(input.options.isMonitoringEnabled()).andReturn(false);
expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata); expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata);
expect( expect(

View File

@ -32,6 +32,7 @@ import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RootDeviceType; import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
@ -73,11 +74,11 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), "0", ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), "0",
"ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f", "ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f",
InstanceState.RUNNING, InstanceType.M1_SMALL, "174.129.81.68", "aki-a71cf9ce", InstanceState.RUNNING, InstanceType.M1_SMALL, "174.129.81.68", "aki-a71cf9ce",
"adriancole.ec21", dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"), false, "adriancole.ec21", dateService.iso8601DateParse("2009-11-09T03:00:34.000Z"),
AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal", MonitoringState.DISABLED, AvailabilityZone.US_EAST_1C, null, "paravirtual", null,
"10.243.42.70", ImmutableSet.<String> of(), "ari-a51cf9cc", null, null, null, "ip-10-243-42-70.ec2.internal", "10.243.42.70", ImmutableSet.<String> of(), "ari-a51cf9cc",
RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())), null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap
"993194456877", null, "r-a3c508cb")); .<String, EbsBlockDevice> of())), "993194456877", null, "r-a3c508cb"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -93,17 +94,17 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23",
"ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64341", InstanceState.RUNNING, "ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64341", InstanceState.RUNNING,
InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService
.iso8601DateParse("2007-08-07T11:54:42.000Z"), false, AvailabilityZone.US_EAST_1B, .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED,
null, "paravirtual", null, "10-251-50-132.ec2.internal", null, ImmutableSet.of("774F4FF8"), AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null,
"ari-badbad00", null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap
.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435",
InstanceState.RUNNING, InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3",
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:54:42.000Z"), false,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null,
ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, RootDeviceType.INSTANCE_STORE, ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, RootDeviceType.INSTANCE_STORE,
null, ImmutableMap.<String, EbsBlockDevice> of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, null, ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion,
"r-44a5402d")); ImmutableSet.of("default"), "23", "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007",
"i-28a64435", InstanceState.RUNNING, InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3",
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:54:42.000Z"),
MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null,
"10-251-50-134.ec2.internal", null, ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null,
null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of())),
"UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -120,10 +121,10 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
contents.add(new Reservation<RunningInstance>(defaultRegion, ImmutableSet.of("default"), ImmutableSet contents.add(new Reservation<RunningInstance>(defaultRegion, ImmutableSet.of("default"), ImmutableSet
.of(new RunningInstance(defaultRegion, ImmutableSet.of("jclouds#euc"), "1", null, "emi-9ACB1363", .of(new RunningInstance(defaultRegion, ImmutableSet.of("jclouds#euc"), "1", null, "emi-9ACB1363",
"i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2", "i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2",
"jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), false, "open", "jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"),
null, "paravirtual", null, "10.7.0.179", null, ImmutableSet.<String> of(), "eri-A97113E4", MonitoringState.DISABLED, "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet
null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap .<String> of(), "eri-A97113E4", null, null, null, RootDeviceType.INSTANCE_STORE, null,
.<String, EbsBlockDevice> of())), "jclouds", null, "r-4D2A08AD")); ImmutableMap.<String, EbsBlockDevice> of())), "jclouds", null, "r-4D2A08AD"));
Set<Reservation<? extends RunningInstance>> result = getReservations(is); Set<Reservation<? extends RunningInstance>> result = getReservations(is);
@ -139,8 +140,8 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest {
ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), "0", ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), "0",
"ec2-75-101-203-146.compute-1.amazonaws.com", "ami-849875ed", "i-e564438d", "ec2-75-101-203-146.compute-1.amazonaws.com", "ami-849875ed", "i-e564438d",
InstanceState.RUNNING, InstanceType.M1_SMALL, "75.101.203.146", "aki-a71cf9ce", InstanceState.RUNNING, InstanceType.M1_SMALL, "75.101.203.146", "aki-a71cf9ce",
"adriancole.ec2ebs1", dateService.iso8601DateParse("2009-12-30T04:06:23.000Z"), false, "adriancole.ec2ebs1", dateService.iso8601DateParse("2009-12-30T04:06:23.000Z"),
AvailabilityZone.US_EAST_1B, "placement", "hvm", null, MonitoringState.DISABLED, AvailabilityZone.US_EAST_1B, "placement", "hvm", null,
"domU-12-31-39-09-CE-53.compute-1.internal", "10.210.209.157", ImmutableSet.<String> of(), "domU-12-31-39-09-CE-53.compute-1.internal", "10.210.209.157", ImmutableSet.<String> of(),
"ari-a51cf9cc", null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap "ari-a51cf9cc", null, null, null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap
.<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice("vol-dc6ca8b5", .<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice("vol-dc6ca8b5",

View File

@ -29,6 +29,7 @@ import java.io.InputStream;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.ec2.domain.Reservation; import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RootDeviceType; import org.jclouds.aws.ec2.domain.RootDeviceType;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
@ -68,19 +69,19 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest {
Reservation<? extends RunningInstance> expected = new Reservation<RunningInstance>(defaultRegion, ImmutableSet Reservation<? extends RunningInstance> expected = new Reservation<RunningInstance>(defaultRegion, ImmutableSet
.of("default"), ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("default"), "0", .of("default"), ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("default"), "0",
null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null,
"example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED,
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets
.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, .<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL, .of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, Sets.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet ImmutableMap.<String, EbsBlockDevice> of()), new RunningInstance(defaultRegion, ImmutableSet
.of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL, .of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL,
(String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), true, (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"),
AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null,
.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null, Sets.<String> newLinkedHashSet(), null, null, null, null, RootDeviceType.INSTANCE_STORE, null,
ImmutableMap.<String, EbsBlockDevice> of()) ImmutableMap.<String, EbsBlockDevice> of())
), "AIDADH4IGTRXXKCD", null, "r-47a5402e"); ), "AIDADH4IGTRXXKCD", null, "r-47a5402e");

View File

@ -28,8 +28,8 @@ import java.util.Properties;
import javax.inject.Named; import javax.inject.Named;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.aws.ec2.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.elb.config.ELBRestClientModule; import org.jclouds.aws.elb.config.ELBRestClientModule;
import org.jclouds.aws.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;

View File

@ -17,13 +17,14 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.xml; package org.jclouds.aws.elb.xml;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import java.util.Set; import java.util.Set;
import org.jclouds.aws.ec2.xml.BaseEC2HandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;

View File

@ -92,6 +92,8 @@ public class ParseAWSErrorFromXmlContentTest {
HttpRequest request = new HttpRequest(method, uri); HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
.toInputStream(content))); .toInputStream(content)));
response.getPayload().setContentType("text/xml");
//TODO also check application/unknown
expect(command.getRequest()).andReturn(request).atLeastOnce(); expect(command.getRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected)); command.setException(classEq(expected));

View File

@ -57,8 +57,7 @@ public class AWSUtilsTest {
protected void setUpInjector() throws IOException { protected void setUpInjector() throws IOException {
Injector injector = new RestContextFactory().createContextBuilder("s3", "foo", "bar", Injector injector = new RestContextFactory().createContextBuilder("s3", "foo", "bar",
ImmutableSet.of(new MockModule(), new NullLoggingModule()), new Properties()) ImmutableSet.of(new MockModule(), new NullLoggingModule()), new Properties()).buildInjector();
.buildInjector();
utils = injector.getInstance(AWSUtils.class); utils = injector.getInstance(AWSUtils.class);
@ -74,6 +73,7 @@ public class AWSUtilsTest {
HttpResponse response(InputStream content) { HttpResponse response(InputStream content) {
HttpResponse response = new HttpResponse(400, "boa", Payloads.newInputStreamPayload(content)); HttpResponse response = new HttpResponse(400, "boa", Payloads.newInputStreamPayload(content));
response.getPayload().setContentType("text/xml");
response.getHeaders().put("x-amz-request-id", "requestid"); response.getHeaders().put("x-amz-request-id", "requestid");
response.getHeaders().put("x-amz-id-2", "requesttoken"); response.getHeaders().put("x-amz-id-2", "requesttoken");
return response; return response;
@ -81,8 +81,8 @@ public class AWSUtilsTest {
@Test @Test
public void testParseAWSErrorFromContentHttpCommandHttpResponseInputStream() { public void testParseAWSErrorFromContentHttpCommandHttpResponseInputStream() {
AWSError error = utils.parseAWSErrorFromContent(command.getRequest(), response(getClass() AWSError error = utils.parseAWSErrorFromContent(command.getRequest(), response(getClass().getResourceAsStream(
.getResourceAsStream("/error.xml"))); "/error.xml")));
assertEquals(error.getCode(), "NoSuchKey"); assertEquals(error.getCode(), "NoSuchKey");
assertEquals(error.getMessage(), "The resource you requested does not exist"); assertEquals(error.getMessage(), "The resource you requested does not exist");
assertEquals(error.getRequestToken(), "requesttoken"); assertEquals(error.getRequestToken(), "requesttoken");

View File

@ -0,0 +1,22 @@
<GetMetricStatisticsResponse>
<GetMetricStatisticsResult>
<Datapoints>
<member>
<Timestamp>2009-01-16T00:00:00Z</Timestamp>
<Unit>Percent</Unit>
<Samples>9.0</Samples>
<Average>0.17777777777777778</Average>
</member>
<member>
<Timestamp>2009-01-16T00:01:00Z</Timestamp>
<Unit>Percent</Unit>
<Samples>8.0</Samples>
<Average>0.1</Average>
</member>
</Datapoints>
<Label>CPUUtilization</Label>
</GetMetricStatisticsResult>
<ResponseMetadata>
<RequestId>a9f8f3a3-e40f-11dd-af0f-cf11f65ec49d</RequestId>
</ResponseMetadata>
</GetMetricStatisticsResponse>

View File

@ -1,59 +1,73 @@
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/"> <DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<reservationSet> <reservationSet>
<item>
<reservationId>r-44a5402d</reservationId>
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
<groupSet>
<item> <item>
<groupId>default</groupId> <reservationId>r-44a5402d</reservationId>
<ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId>
<groupSet>
<item>
<groupId>default</groupId>
</item>
</groupSet>
<instancesSet>
<item>
<instanceId>i-28a64341</instanceId>
<imageId>ami-6ea54007</imageId>
<instanceState>
<code>0</code>
<name>running</name>
</instanceState>
<privateDnsName>10-251-50-132.ec2.internal
</privateDnsName>
<dnsName>ec2-72-44-33-4.compute-1.amazonaws.com
</dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>23</amiLaunchIndex>
<productCodesSet>
<item>
<productCode>774F4FF8</productCode>
</item>
</productCodesSet>
<instanceType>m1.large</instanceType>
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
<monitoring>
<state>disabled</state>
</monitoring>
<kernelId>aki-ba3adfd3</kernelId>
<ramdiskId>ari-badbad00</ramdiskId>
</item>
<item>
<instanceId>i-28a64435</instanceId>
<imageId>ami-6ea54007</imageId>
<instanceState>
<code>0</code>
<name>running</name>
</instanceState>
<privateDnsName>10-251-50-134.ec2.internal
</privateDnsName>
<dnsName>ec2-72-44-33-6.compute-1.amazonaws.com
</dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>23</amiLaunchIndex>
<productCodesSet>
<item>
<productCode>774F4FF8</productCode>
</item>
</productCodesSet>
<instanceType>m1.large</instanceType>
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
<monitoring>
<state>disabled</state>
</monitoring>
<kernelId>aki-ba3adfd3</kernelId>
<ramdiskId>ari-badbad00</ramdiskId>
</item>
</instancesSet>
</item> </item>
</groupSet> </reservationSet>
<instancesSet>
<item>
<instanceId>i-28a64341</instanceId>
<imageId>ami-6ea54007</imageId>
<instanceState>
<code>0</code>
<name>running</name>
</instanceState>
<privateDnsName>10-251-50-132.ec2.internal</privateDnsName>
<dnsName>ec2-72-44-33-4.compute-1.amazonaws.com</dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>23</amiLaunchIndex>
<productCodesSet>
<item><productCode>774F4FF8</productCode></item>
</productCodesSet>
<instanceType>m1.large</instanceType>
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
<kernelId>aki-ba3adfd3</kernelId>
<ramdiskId>ari-badbad00</ramdiskId>
</item>
<item>
<instanceId>i-28a64435</instanceId>
<imageId>ami-6ea54007</imageId>
<instanceState>
<code>0</code>
<name>running</name>
</instanceState>
<privateDnsName>10-251-50-134.ec2.internal</privateDnsName>
<dnsName>ec2-72-44-33-6.compute-1.amazonaws.com</dnsName>
<keyName>example-key-name</keyName>
<amiLaunchIndex>23</amiLaunchIndex>
<productCodesSet>
<item><productCode>774F4FF8</productCode></item>
</productCodesSet>
<instanceType>m1.large</instanceType>
<launchTime>2007-08-07T11:54:42.000Z</launchTime>
<placement>
<availabilityZone>us-east-1b</availabilityZone>
</placement>
<kernelId>aki-ba3adfd3</kernelId>
<ramdiskId>ari-badbad00</ramdiskId>
</item>
</instancesSet>
</item>
</reservationSet>
</DescribeInstancesResponse> </DescribeInstancesResponse>

View File

@ -24,7 +24,7 @@
<availabilityZone>us-east-1b</availabilityZone> <availabilityZone>us-east-1b</availabilityZone>
</placement> </placement>
<monitoring> <monitoring>
<enabled>true</enabled> <state>enabled</state>
</monitoring> </monitoring>
</item> </item>
<item> <item>
@ -44,7 +44,7 @@
<availabilityZone>us-east-1b</availabilityZone> <availabilityZone>us-east-1b</availabilityZone>
</placement> </placement>
<monitoring> <monitoring>
<enabled>true</enabled> <state>enabled</state>
</monitoring> </monitoring>
</item> </item>
<item> <item>
@ -64,7 +64,7 @@
<availabilityZone>us-east-1b</availabilityZone> <availabilityZone>us-east-1b</availabilityZone>
</placement> </placement>
<monitoring> <monitoring>
<enabled>true</enabled> <state>enabled</state>
</monitoring> </monitoring>
</item> </item>
</instancesSet> </instancesSet>

View File

@ -38,6 +38,9 @@ sqs.propertiesbuilder=org.jclouds.aws.sqs.SQSPropertiesBuilder
elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder
elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder
cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder
s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder