mirror of https://github.com/apache/jclouds.git
Merge pull request #1350 from abayer/master
EC2 Subnet added, with DescribeSubnets support initially.
This commit is contained in:
commit
94c9e00e7b
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.ec2;
|
package org.jclouds.ec2;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.jclouds.ec2.features.SubnetApi;
|
||||||
import org.jclouds.ec2.features.TagApi;
|
import org.jclouds.ec2.features.TagApi;
|
||||||
import org.jclouds.ec2.features.WindowsApi;
|
import org.jclouds.ec2.features.WindowsApi;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
@ -77,4 +78,14 @@ public interface EC2Api {
|
||||||
@Delegate
|
@Delegate
|
||||||
Optional<? extends TagApi> getTagApiForRegion(
|
Optional<? extends TagApi> getTagApiForRegion(
|
||||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Subnet features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<? extends SubnetApi> getSubnetApi();
|
||||||
|
|
||||||
|
@Delegate
|
||||||
|
Optional<? extends SubnetApi> getSubnetApiForRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.ec2;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.features.SubnetAsyncApi;
|
||||||
import org.jclouds.ec2.features.TagAsyncApi;
|
import org.jclouds.ec2.features.TagAsyncApi;
|
||||||
import org.jclouds.ec2.features.WindowsAsyncApi;
|
import org.jclouds.ec2.features.WindowsAsyncApi;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
@ -65,4 +66,14 @@ public interface EC2AsyncApi {
|
||||||
@Delegate
|
@Delegate
|
||||||
Optional<? extends TagAsyncApi> getTagApiForRegion(
|
Optional<? extends TagAsyncApi> getTagApiForRegion(
|
||||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Subnet features.
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
Optional<? extends SubnetAsyncApi> getSubnetApi();
|
||||||
|
|
||||||
|
@Delegate
|
||||||
|
Optional<? extends SubnetAsyncApi> getSubnetApiForRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ import org.jclouds.ec2.compute.options.EC2TemplateOptions;
|
||||||
import org.jclouds.ec2.domain.KeyPair;
|
import org.jclouds.ec2.domain.KeyPair;
|
||||||
import org.jclouds.ec2.domain.RunningInstance;
|
import org.jclouds.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.ec2.domain.Tag;
|
import org.jclouds.ec2.domain.Tag;
|
||||||
|
import org.jclouds.ec2.util.SubnetFilterBuilder;
|
||||||
import org.jclouds.ec2.util.TagFilterBuilder;
|
import org.jclouds.ec2.util.TagFilterBuilder;
|
||||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ import org.jclouds.ec2.EC2Api;
|
||||||
import org.jclouds.ec2.EC2AsyncApi;
|
import org.jclouds.ec2.EC2AsyncApi;
|
||||||
import org.jclouds.ec2.EC2AsyncClient;
|
import org.jclouds.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.ec2.EC2Client;
|
import org.jclouds.ec2.EC2Client;
|
||||||
|
import org.jclouds.ec2.features.SubnetApi;
|
||||||
|
import org.jclouds.ec2.features.SubnetAsyncApi;
|
||||||
import org.jclouds.ec2.features.TagApi;
|
import org.jclouds.ec2.features.TagApi;
|
||||||
import org.jclouds.ec2.features.TagAsyncApi;
|
import org.jclouds.ec2.features.TagAsyncApi;
|
||||||
import org.jclouds.ec2.features.WindowsApi;
|
import org.jclouds.ec2.features.WindowsApi;
|
||||||
|
@ -87,6 +89,7 @@ public class EC2RestClientModule<S extends EC2Api, A extends EC2AsyncApi> extend
|
||||||
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
|
||||||
.put(WindowsApi.class, WindowsAsyncApi.class)//
|
.put(WindowsApi.class, WindowsAsyncApi.class)//
|
||||||
.put(TagApi.class, TagAsyncApi.class)//
|
.put(TagApi.class, TagAsyncApi.class)//
|
||||||
|
.put(SubnetApi.class, SubnetAsyncApi.class)//
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amazon EC2 VPCs contain one or more subnets.
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html"
|
||||||
|
* >doc</a>
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
public class Subnet {
|
||||||
|
|
||||||
|
public static enum State {
|
||||||
|
/**
|
||||||
|
* The subnet is available for use.
|
||||||
|
*/
|
||||||
|
AVAILABLE,
|
||||||
|
/**
|
||||||
|
* The subnet is not yet available for use.
|
||||||
|
*/
|
||||||
|
PENDING, UNRECOGNIZED;
|
||||||
|
public String value() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static State fromValue(String v) {
|
||||||
|
try {
|
||||||
|
return valueOf(v.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String subnetId;
|
||||||
|
private final State subnetState;
|
||||||
|
private final String vpcId;
|
||||||
|
private final String cidrBlock;
|
||||||
|
private final int availableIpAddressCount;
|
||||||
|
private final String availabilityZone;
|
||||||
|
private final Map<String, String> tags;
|
||||||
|
|
||||||
|
public Subnet(String subnetId, State subnetState, String vpcId, String cidrBlock,
|
||||||
|
int availableIpAddressCount, String availabilityZone, Map<String, String> tags) {
|
||||||
|
this.subnetId = checkNotNull(subnetId, "subnetId");
|
||||||
|
this.subnetState = checkNotNull(subnetState, "subnetState for %s", subnetId);
|
||||||
|
this.vpcId = checkNotNull(vpcId, "vpcId for %s", subnetId);
|
||||||
|
this.cidrBlock = checkNotNull(cidrBlock, "cidrBlock for %s", subnetId);
|
||||||
|
this.availableIpAddressCount = availableIpAddressCount;
|
||||||
|
this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone for %s", subnetId);
|
||||||
|
this.tags = ImmutableMap.<String, String> copyOf(checkNotNull(tags, "tags for %s", subnetId));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subnet ID, ex. subnet-c5473ba8
|
||||||
|
*/
|
||||||
|
public String getSubnetId() {
|
||||||
|
return subnetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subnet state - either available or pending.
|
||||||
|
*/
|
||||||
|
public State getSubnetState() {
|
||||||
|
return subnetState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The vpc ID this subnet belongs to.
|
||||||
|
*/
|
||||||
|
public String getVpcId() {
|
||||||
|
return vpcId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CIDR block for this subnet.
|
||||||
|
*/
|
||||||
|
public String getCidrBlock() {
|
||||||
|
return cidrBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of available IPs in this subnet.
|
||||||
|
*/
|
||||||
|
public int getAvailableIpAddressCount() {
|
||||||
|
return availableIpAddressCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The availability zone this subnet is in.
|
||||||
|
*/
|
||||||
|
public String getAvailabilityZone() {
|
||||||
|
return availabilityZone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tags that are attached to this subnet.
|
||||||
|
*/
|
||||||
|
public Map<String, String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(subnetId, vpcId, availabilityZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Subnet other = (Subnet) obj;
|
||||||
|
return Objects.equal(this.subnetId, other.subnetId)
|
||||||
|
&& Objects.equal(this.vpcId, other.vpcId)
|
||||||
|
&& Objects.equal(this.availabilityZone, other.availabilityZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return string().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ToStringHelper string() {
|
||||||
|
return Objects.toStringHelper(this).omitNullValues().add("subnetId", subnetId)
|
||||||
|
.add("subnetState", subnetState).add("vpcId", vpcId)
|
||||||
|
.add("cidrBlock", cidrBlock).add("availableIpAddressCount", availableIpAddressCount)
|
||||||
|
.add("availabilityZone", availabilityZone).add("tags", tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromSubnet(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private String subnetId;
|
||||||
|
private State subnetState;
|
||||||
|
private String vpcId;
|
||||||
|
private String cidrBlock;
|
||||||
|
private int availableIpAddressCount;
|
||||||
|
private String availabilityZone;
|
||||||
|
private Map<String, String> tags = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getSubnetId()
|
||||||
|
*/
|
||||||
|
public Builder subnetId(String subnetId) {
|
||||||
|
this.subnetId = subnetId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getState()
|
||||||
|
*/
|
||||||
|
public Builder subnetState(State subnetState) {
|
||||||
|
this.subnetState = subnetState;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getVpcId()
|
||||||
|
*/
|
||||||
|
public Builder vpcId(String vpcId) {
|
||||||
|
this.vpcId = vpcId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getCidrBlock()
|
||||||
|
*/
|
||||||
|
public Builder cidrBlock(String cidrBlock) {
|
||||||
|
this.cidrBlock = cidrBlock;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getAvailableIpAddressCount()
|
||||||
|
*/
|
||||||
|
public Builder availableIpAddressCount(int availableIpAddressCount) {
|
||||||
|
this.availableIpAddressCount = availableIpAddressCount;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getAvailabilityZone()
|
||||||
|
*/
|
||||||
|
public Builder availabilityZone(String availabilityZone) {
|
||||||
|
this.availabilityZone = availabilityZone;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getTags()
|
||||||
|
*/
|
||||||
|
public Builder tags(Map<String, String> tags) {
|
||||||
|
this.tags = ImmutableMap.copyOf(checkNotNull(tags, "tags"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Subnet#getTags()
|
||||||
|
*/
|
||||||
|
public Builder tag(String key, String value) {
|
||||||
|
if (key != null)
|
||||||
|
this.tags.put(key, Strings.nullToEmpty(value));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Subnet build() {
|
||||||
|
return new Subnet(subnetId, subnetState, vpcId, cidrBlock, availableIpAddressCount,
|
||||||
|
availabilityZone, tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromSubnet(Subnet in) {
|
||||||
|
return this.subnetId(in.getSubnetId())
|
||||||
|
.subnetState(in.getSubnetState())
|
||||||
|
.vpcId(in.getVpcId())
|
||||||
|
.cidrBlock(in.getCidrBlock())
|
||||||
|
.availableIpAddressCount(in.getAvailableIpAddressCount())
|
||||||
|
.availabilityZone(in.getAvailabilityZone())
|
||||||
|
.tags(in.getTags());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.features;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.util.SubnetFilterBuilder;
|
||||||
|
import org.jclouds.rest.annotations.SinceApiVersion;
|
||||||
|
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To help you manage your Amazon EC2 instances, images, and other Amazon EC2
|
||||||
|
* resources, you can assign your own metadata to each resource in the form of
|
||||||
|
* tags.
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Subnets.html"
|
||||||
|
* >doc</a>
|
||||||
|
* @see SubnetAsyncApi
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
@SinceApiVersion("2011-01-01")
|
||||||
|
public interface SubnetApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes all of your subnets for your EC2 resources.
|
||||||
|
*
|
||||||
|
* @return subnets or empty if there are none
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
|
||||||
|
* >docs</href>
|
||||||
|
*/
|
||||||
|
FluentIterable<Subnet> list();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes subnets for your EC2 resources qualified by a filter
|
||||||
|
*
|
||||||
|
* <h4>example</h4>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* subnets = subnetApi.filter(new SubnetFilterBuilder().vpcId("vpc-1a2b3c4d").build());
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param filter
|
||||||
|
* which is typically built by {@link SubnetFilterBuilder}
|
||||||
|
* @return tags or empty if there are none that match the filter
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
|
||||||
|
* >docs</href>
|
||||||
|
*/
|
||||||
|
FluentIterable<Subnet> filter(Multimap<String, String> filter);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.features;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.reference.FormParameters.ACTION;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
|
||||||
|
import org.jclouds.aws.filters.FormSigner;
|
||||||
|
import org.jclouds.ec2.binders.BindFiltersToIndexedFormParams;
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.xml.DescribeSubnetsResponseHandler;
|
||||||
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.FormParams;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SinceApiVersion;
|
||||||
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to Amazon EC2 via the Query API
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
|
||||||
|
* >doc</a>
|
||||||
|
* @see SubnetApi
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
@SinceApiVersion("2011-01-01")
|
||||||
|
@RequestFilters(FormSigner.class)
|
||||||
|
@VirtualHost
|
||||||
|
public interface SubnetAsyncApi {
|
||||||
|
/**
|
||||||
|
* @see SubnetApi#list()
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html">docs</a>
|
||||||
|
*/
|
||||||
|
@Named("DescribeSubnets")
|
||||||
|
@POST
|
||||||
|
@Path("/")
|
||||||
|
@FormParams(keys = ACTION, values = "DescribeSubnets")
|
||||||
|
@XMLResponseParser(DescribeSubnetsResponseHandler.class)
|
||||||
|
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<FluentIterable<Subnet>> list();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SubnetApi#filter
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html">docs</a>
|
||||||
|
*/
|
||||||
|
@Named("DescribeSubnets")
|
||||||
|
@POST
|
||||||
|
@Path("/")
|
||||||
|
@FormParams(keys = ACTION, values = "DescribeSubnets")
|
||||||
|
@XMLResponseParser(DescribeSubnetsResponseHandler.class)
|
||||||
|
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<FluentIterable<Subnet>> filter(
|
||||||
|
@BinderParam(BindFiltersToIndexedFormParams.class) Multimap<String, String> filter);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,254 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.util;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.features.SubnetApi;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You can specify filters so that the response includes information for only
|
||||||
|
* certain subnets. For example, you can use a filter to specify that you're
|
||||||
|
* interested in the subnets in the available state. You can specify multiple
|
||||||
|
* values for a filter. The response includes information for a subnet only if
|
||||||
|
* it matches at least one of the filter values that you specified.
|
||||||
|
*
|
||||||
|
* You can specify multiple filters; for example, specify subnets that are in a
|
||||||
|
* specific VPC and are in the available state. The response includes
|
||||||
|
* information for a subnet only if it matches all the filters that you
|
||||||
|
* specified. If there's no match, no special message is returned, the response
|
||||||
|
* is simply empty.
|
||||||
|
*
|
||||||
|
* <h4>Wildcards</h4> You can use wildcards with the filter values: {@code *}
|
||||||
|
* matches zero or more characters, and ? matches exactly one character. You can
|
||||||
|
* escape special characters using a backslash before the character. For
|
||||||
|
* example, a value of {@code \*amazon\?\\} searches for the literal string
|
||||||
|
* {@code *amazon?\}.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
* @see SubnetApi
|
||||||
|
*/
|
||||||
|
public class SubnetFilterBuilder extends ImmutableMultimap.Builder<String, String> {
|
||||||
|
|
||||||
|
private static final String AVAILABILITY_ZONE = "availability-zone";
|
||||||
|
private static final String AVAILABLE_IP_ADDRESS_COUNT = "available-ip-address-count";
|
||||||
|
private static final String CIDR = "cidr";
|
||||||
|
private static final String STATE = "state";
|
||||||
|
private static final String SUBNET_ID = "subnet-id";
|
||||||
|
private static final String TAG_KEY = "tag-key";
|
||||||
|
private static final String TAG_VALUE = "tag-value";
|
||||||
|
private static final String TAG_ARBITRARY_BASE = "tag:";
|
||||||
|
private static final String VPC_ID = "vpc-id";
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availabilityZone(String availabilityZone) {
|
||||||
|
return put(AVAILABILITY_ZONE, availabilityZone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availabilityZones(String... availabilityZones) {
|
||||||
|
return putAll(AVAILABILITY_ZONE, availabilityZones);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availabilityZones(Iterable<String> availabilityZones) {
|
||||||
|
return putAll(AVAILABILITY_ZONE, availabilityZones);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyAvailabilityZone() {
|
||||||
|
return putAll(AVAILABILITY_ZONE, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availableIpAddressCount(String availableIpAddressCount) {
|
||||||
|
return put(AVAILABLE_IP_ADDRESS_COUNT, availableIpAddressCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availableIpAddressCounts(String... availableIpAddressCounts) {
|
||||||
|
return putAll(AVAILABLE_IP_ADDRESS_COUNT, availableIpAddressCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder availableIpAddressCounts(Iterable<String> availableIpAddressCounts) {
|
||||||
|
return putAll(AVAILABLE_IP_ADDRESS_COUNT, availableIpAddressCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyAvailableIpAddressCount() {
|
||||||
|
return putAll(AVAILABLE_IP_ADDRESS_COUNT, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder cidr(String cidr) {
|
||||||
|
return put(CIDR, cidr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder cidrs(String... cidrs) {
|
||||||
|
return putAll(CIDR, cidrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder cidrs(Iterable<String> cidrs) {
|
||||||
|
return putAll(CIDR, cidrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyCidr() {
|
||||||
|
return putAll(CIDR, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder state(String state) {
|
||||||
|
return put(STATE, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder states(String... states) {
|
||||||
|
return putAll(STATE, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder states(Iterable<String> states) {
|
||||||
|
return putAll(STATE, states);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyState() {
|
||||||
|
return putAll(STATE, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder available() {
|
||||||
|
return put(STATE, Subnet.State.AVAILABLE.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder pending() {
|
||||||
|
return put(STATE, Subnet.State.PENDING.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder subnetId(String subnetId) {
|
||||||
|
return put(SUBNET_ID, subnetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder subnetIds(String... subnetIds) {
|
||||||
|
return putAll(SUBNET_ID, subnetIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder subnetIds(Iterable<String> subnetIds) {
|
||||||
|
return putAll(SUBNET_ID, subnetIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anySubnetId() {
|
||||||
|
return putAll(SUBNET_ID, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagKey(String tagKey) {
|
||||||
|
return put(TAG_KEY, tagKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagKeys(String... tagKeys) {
|
||||||
|
return putAll(TAG_KEY, tagKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagKeys(Iterable<String> tagKeys) {
|
||||||
|
return putAll(TAG_KEY, tagKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyTagKey() {
|
||||||
|
return putAll(TAG_KEY, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagValue(String tagValue) {
|
||||||
|
return put(TAG_VALUE, tagValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagValues(String... tagValues) {
|
||||||
|
return putAll(TAG_VALUE, tagValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder tagValues(Iterable<String> tagValues) {
|
||||||
|
return putAll(TAG_VALUE, tagValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyTagValue() {
|
||||||
|
return putAll(TAG_VALUE, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder vpcId(String vpcId) {
|
||||||
|
return put(VPC_ID, vpcId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder vpcIds(String... vpcIds) {
|
||||||
|
return putAll(VPC_ID, vpcIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder vpcIds(Iterable<String> vpcIds) {
|
||||||
|
return putAll(VPC_ID, vpcIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder anyVpcId() {
|
||||||
|
return putAll(VPC_ID, ImmutableSet.<String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder arbitraryTag(String arbitraryTagKey, String arbitraryTagValue) {
|
||||||
|
return put(TAG_ARBITRARY_BASE + arbitraryTagKey, arbitraryTagValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder arbitraryTag(String arbitraryTagKey, String... arbitraryTagValues) {
|
||||||
|
return putAll(TAG_ARBITRARY_BASE + arbitraryTagKey, arbitraryTagValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubnetFilterBuilder arbitraryTag(String arbitraryTagKey, Iterable<String> arbitraryTagValues) {
|
||||||
|
return putAll(TAG_ARBITRARY_BASE + arbitraryTagKey, arbitraryTagValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to set correct return val in chain
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubnetFilterBuilder put(String key, String value) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.put(key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubnetFilterBuilder put(Entry<? extends String, ? extends String> entry) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.put(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubnetFilterBuilder putAll(String key, Iterable<? extends String> values) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.putAll(key, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubnetFilterBuilder putAll(String key, String... values) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.putAll(key, values));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubnetFilterBuilder putAll(Multimap<? extends String, ? extends String> multimap) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.putAll(multimap));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Beta
|
||||||
|
public SubnetFilterBuilder orderKeysBy(Comparator<? super String> keyComparator) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.orderKeysBy(keyComparator));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Beta
|
||||||
|
public SubnetFilterBuilder orderValuesBy(Comparator<? super String> valueComparator) {
|
||||||
|
return SubnetFilterBuilder.class.cast(super.orderValuesBy(valueComparator));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.xml;
|
||||||
|
|
||||||
|
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||||
|
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSubnets.html"
|
||||||
|
* >xml</a>
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
public class DescribeSubnetsResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<FluentIterable<Subnet>> {
|
||||||
|
private final SubnetHandler subnetHandler;
|
||||||
|
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
private boolean inSubnetSet;
|
||||||
|
private boolean inTagSet;
|
||||||
|
private Builder<Subnet> subnets = ImmutableSet.<Subnet> builder();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public DescribeSubnetsResponseHandler(SubnetHandler subnetHandler) {
|
||||||
|
this.subnetHandler = subnetHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FluentIterable<Subnet> getResult() {
|
||||||
|
return FluentIterable.from(subnets.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (equalsOrSuffix(qName, "subnetSet")) {
|
||||||
|
inSubnetSet = true;
|
||||||
|
} else if (inSubnetSet) {
|
||||||
|
if (equalsOrSuffix(qName, "tagSet")) {
|
||||||
|
inTagSet = true;
|
||||||
|
}
|
||||||
|
subnetHandler.startElement(url, name, qName, attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String name, String qName) throws SAXException {
|
||||||
|
if (equalsOrSuffix(qName, "subnetSet")) {
|
||||||
|
inSubnetSet = false;
|
||||||
|
} else if (equalsOrSuffix(qName, "tagSet")) {
|
||||||
|
inTagSet = false;
|
||||||
|
subnetHandler.endElement(uri, name, qName);
|
||||||
|
} else if (equalsOrSuffix(qName, "item") && !inTagSet) {
|
||||||
|
subnets.add(subnetHandler.getResult());
|
||||||
|
} else if (inSubnetSet) {
|
||||||
|
subnetHandler.endElement(uri, name, qName);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
if (inSubnetSet) {
|
||||||
|
subnetHandler.characters(ch, start, length);
|
||||||
|
} else {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.xml;
|
||||||
|
|
||||||
|
import static org.jclouds.util.SaxUtils.currentOrNull;
|
||||||
|
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.domain.Subnet.State;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-ItemType-SubnetType.html"
|
||||||
|
* >xml</a>
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
public class SubnetHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Subnet> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
private Subnet.Builder builder = newBuilder();
|
||||||
|
private final TagSetHandler tagSetHandler;
|
||||||
|
private boolean inTagSet;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SubnetHandler(TagSetHandler tagSetHandler) {
|
||||||
|
this.tagSetHandler = tagSetHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Subnet getResult() {
|
||||||
|
try {
|
||||||
|
return builder.build();
|
||||||
|
} finally {
|
||||||
|
builder = Subnet.builder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String name, String qName, Attributes attrs) {
|
||||||
|
if (equalsOrSuffix(qName, "tagSet")) {
|
||||||
|
inTagSet = true;
|
||||||
|
}
|
||||||
|
if (inTagSet) {
|
||||||
|
tagSetHandler.startElement(uri, name, qName, attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
if (equalsOrSuffix(qName, "tagSet")) {
|
||||||
|
inTagSet = false;
|
||||||
|
builder.tags(tagSetHandler.getResult());
|
||||||
|
} else if (inTagSet) {
|
||||||
|
tagSetHandler.endElement(uri, name, qName);
|
||||||
|
} else if (equalsOrSuffix(qName, "subnetId")) {
|
||||||
|
builder.subnetId(currentOrNull(currentText));
|
||||||
|
} else if (equalsOrSuffix(qName, "state")) {
|
||||||
|
builder.subnetState(Subnet.State.fromValue(currentOrNull(currentText)));
|
||||||
|
} else if (equalsOrSuffix(qName, "vpcId")) {
|
||||||
|
builder.vpcId(currentOrNull(currentText));
|
||||||
|
} else if (equalsOrSuffix(qName, "cidrBlock")) {
|
||||||
|
builder.cidrBlock(currentOrNull(currentText));
|
||||||
|
} else if (equalsOrSuffix(qName, "availableIpAddressCount")) {
|
||||||
|
builder.availableIpAddressCount(Integer.parseInt(currentOrNull(currentText)));
|
||||||
|
} else if (equalsOrSuffix(qName, "availabilityZone")) {
|
||||||
|
builder.availabilityZone(currentOrNull(currentText));
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
if (inTagSet) {
|
||||||
|
tagSetHandler.characters(ch, start, length);
|
||||||
|
} else {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Subnet.Builder newBuilder() {
|
||||||
|
return Subnet.builder();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.features;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.ec2.EC2Api;
|
||||||
|
import org.jclouds.ec2.internal.BaseEC2ApiExpectTest;
|
||||||
|
import org.jclouds.ec2.parse.DescribeSubnetsResponseTest;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
import org.jclouds.rest.annotations.SinceApiVersion;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class SubnetApiExpectTest extends BaseEC2ApiExpectTest<EC2Api> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SubnetApi
|
||||||
|
* @see SinceApiVersion
|
||||||
|
*/
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties props = super.setupProperties();
|
||||||
|
props.put(Constants.PROPERTY_API_VERSION, "2011-01-01");
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest list = HttpRequest.builder()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint("https://ec2.us-east-1.amazonaws.com/")
|
||||||
|
.addHeader("Host", "ec2.us-east-1.amazonaws.com")
|
||||||
|
.payload(
|
||||||
|
payloadFromStringWithContentType(
|
||||||
|
"Action=DescribeSubnets" +
|
||||||
|
"&Signature=Uuafp9lnYQmMUcf/JE1epPTQVCSMPqfns%2BwlZssUsi4%3D" +
|
||||||
|
"&SignatureMethod=HmacSHA256" +
|
||||||
|
"&SignatureVersion=2" +
|
||||||
|
"&Timestamp=2012-04-16T15%3A54%3A08.897Z" +
|
||||||
|
"&Version=2011-01-01" +
|
||||||
|
"&AWSAccessKeyId=identity",
|
||||||
|
"application/x-www-form-urlencoded"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public void testListWhenResponseIs2xx() throws Exception {
|
||||||
|
|
||||||
|
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
|
||||||
|
.payload(payloadFromResourceWithContentType("/describe_subnets.xml", "text/xml")).build();
|
||||||
|
|
||||||
|
EC2Api apiWhenExist = requestSendsResponse(
|
||||||
|
list, listResponse);
|
||||||
|
|
||||||
|
assertEquals(apiWhenExist.getSubnetApi().get().list().toString(), new DescribeSubnetsResponseTest().expected().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListWhenResponseIs404() throws Exception {
|
||||||
|
|
||||||
|
HttpResponse listResponse = HttpResponse.builder().statusCode(404).build();
|
||||||
|
|
||||||
|
EC2Api apiWhenDontExist = requestSendsResponse(
|
||||||
|
list, listResponse);
|
||||||
|
|
||||||
|
assertEquals(apiWhenDontExist.getSubnetApi().get().list().toSet(), ImmutableSet.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest filter =
|
||||||
|
HttpRequest.builder()
|
||||||
|
.method("POST")
|
||||||
|
.endpoint("https://ec2.us-east-1.amazonaws.com/")
|
||||||
|
.addHeader("Host", "ec2.us-east-1.amazonaws.com")
|
||||||
|
.payload(payloadFromStringWithContentType(
|
||||||
|
"Action=DescribeSubnets" +
|
||||||
|
"&Filter.1.Name=subnet-id" +
|
||||||
|
"&Filter.1.Value.1=subnet-9d4a7b6c" +
|
||||||
|
"&Signature=%2Bp34YACfLk9km1H3eALnDmrkst9FhJttojVSf7VztLk%3D" +
|
||||||
|
"&SignatureMethod=HmacSHA256" +
|
||||||
|
"&SignatureVersion=2" +
|
||||||
|
"&Timestamp=2012-04-16T15%3A54%3A08.897Z" +
|
||||||
|
"&Version=2011-01-01" +
|
||||||
|
"&AWSAccessKeyId=identity",
|
||||||
|
"application/x-www-form-urlencoded"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
public void testFilterWhenResponseIs2xx() throws Exception {
|
||||||
|
|
||||||
|
HttpResponse filterResponse = HttpResponse.builder().statusCode(200)
|
||||||
|
.payload(payloadFromResourceWithContentType("/describe_subnets.xml", "text/xml")).build();
|
||||||
|
|
||||||
|
EC2Api apiWhenExist = requestSendsResponse(filter, filterResponse);
|
||||||
|
|
||||||
|
assertEquals(apiWhenExist.getSubnetApi().get().filter(ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("subnet-id", "subnet-9d4a7b6c")
|
||||||
|
.build()).toString(),
|
||||||
|
new DescribeSubnetsResponseTest().expected().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFilterWhenResponseIs404() throws Exception {
|
||||||
|
|
||||||
|
HttpResponse filterResponse = HttpResponse.builder().statusCode(404).build();
|
||||||
|
|
||||||
|
EC2Api apiWhenDontExist = requestSendsResponse(filter, filterResponse);
|
||||||
|
|
||||||
|
assertEquals(apiWhenDontExist.getSubnetApi().get().filter(ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("subnet-id", "subnet-9d4a7b6c")
|
||||||
|
.build()).toSet(), ImmutableSet.of());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* 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.ec2.features.internal;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static java.lang.String.format;
|
||||||
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
|
import static java.util.logging.Logger.getAnonymousLogger;
|
||||||
|
import static org.jclouds.util.Predicates2.retry;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.features.SubnetApi;
|
||||||
|
import org.jclouds.ec2.internal.BaseEC2ApiLiveTest;
|
||||||
|
import org.jclouds.ec2.util.SubnetFilterBuilder;
|
||||||
|
import org.testng.SkipException;
|
||||||
|
import org.testng.annotations.AfterClass;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests ability to list/filter subnets
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
@Test(groups = "live")
|
||||||
|
public class SubnetApiLiveTest extends BaseEC2ApiLiveTest {
|
||||||
|
private Subnet subnet;
|
||||||
|
|
||||||
|
|
||||||
|
private void checkSubnet(Subnet subnet) {
|
||||||
|
getAnonymousLogger().info(format("subnet %s vpc: %s", subnet.getSubnetId(), subnet.getVpcId()));
|
||||||
|
|
||||||
|
checkNotNull(subnet.getSubnetId(), "Id: Subnet %s", subnet);
|
||||||
|
checkNotNull(subnet.getVpcId(), "VPC: Subnet %s", subnet);
|
||||||
|
checkNotNull(subnet.getSubnetState(), "SubnetState: Subnet %s", subnet);
|
||||||
|
checkNotNull(subnet.getCidrBlock(), "CIDR Block: %s", subnet);
|
||||||
|
checkNotNull(subnet.getAvailabilityZone(), "Availability Zone: %s", subnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListSubnets() {
|
||||||
|
ImmutableSet<Subnet> subnets = api().list().toSet();
|
||||||
|
getAnonymousLogger().info("subnets: " + subnets.size());
|
||||||
|
|
||||||
|
for (Subnet subnet : subnets) {
|
||||||
|
checkSubnet(subnet);
|
||||||
|
assertEquals(api().filter(new SubnetFilterBuilder().subnetId(subnet.getSubnetId()).build()).get(0), subnet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFilterWhenNotFound() {
|
||||||
|
assertTrue(retry(new Predicate<Iterable<Subnet>>() {
|
||||||
|
public boolean apply(Iterable<Subnet> input) {
|
||||||
|
return api().filter(new SubnetFilterBuilder().subnetId("subnet-pants").build())
|
||||||
|
.toSet().equals(input);
|
||||||
|
}
|
||||||
|
}, 600, 200, 200, MILLISECONDS).apply(ImmutableSet.<Subnet> of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SubnetApi api() {
|
||||||
|
Optional<? extends SubnetApi> subnetOption = context.getApi().getSubnetApi();
|
||||||
|
if (!subnetOption.isPresent())
|
||||||
|
throw new SkipException("subnet api not present");
|
||||||
|
return subnetOption.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.ec2.parse;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jclouds.ec2.domain.Subnet;
|
||||||
|
import org.jclouds.ec2.xml.DescribeSubnetsResponseHandler;
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @author Andrew Bayer
|
||||||
|
*/
|
||||||
|
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||||
|
@Test(groups = "unit", testName = "DescribeSubnetsResponseTest")
|
||||||
|
public class DescribeSubnetsResponseTest extends BaseHandlerTest {
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/describe_subnets.xml");
|
||||||
|
|
||||||
|
FluentIterable<Subnet> expected = expected();
|
||||||
|
|
||||||
|
DescribeSubnetsResponseHandler handler = injector.getInstance(DescribeSubnetsResponseHandler.class);
|
||||||
|
FluentIterable<Subnet> result = factory.create(handler).parse(is);
|
||||||
|
|
||||||
|
assertEquals(result.toString(), expected.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
public FluentIterable<Subnet> expected() {
|
||||||
|
return FluentIterable.from(ImmutableSet.<Subnet>builder()
|
||||||
|
.add(Subnet.builder()
|
||||||
|
.subnetId("subnet-9d4a7b6c")
|
||||||
|
.subnetState(Subnet.State.AVAILABLE)
|
||||||
|
.vpcId("vpc-1a2b3c4d")
|
||||||
|
.cidrBlock("10.0.1.0/24")
|
||||||
|
.availableIpAddressCount(250)
|
||||||
|
.availabilityZone("us-east-1a")
|
||||||
|
.tag("Name", "ec2-o")
|
||||||
|
.tag("Empty", "")
|
||||||
|
.build())
|
||||||
|
.add(Subnet.builder()
|
||||||
|
.subnetId("subnet-6e7f829e")
|
||||||
|
.subnetState(Subnet.State.AVAILABLE)
|
||||||
|
.vpcId("vpc-1a2b3c4d")
|
||||||
|
.cidrBlock("10.0.0.0/24")
|
||||||
|
.availableIpAddressCount(250)
|
||||||
|
.availabilityZone("us-east-1a")
|
||||||
|
.build()).build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,8 @@ import com.google.common.collect.ImmutableSet;
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit")
|
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
|
||||||
|
@Test(groups = "unit", testName = "DescribeTagsResponseTest")
|
||||||
public class DescribeTagsResponseTest extends BaseHandlerTest {
|
public class DescribeTagsResponseTest extends BaseHandlerTest {
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<DescribeSubnetsResponse xmlns="http://ec2.amazonaws.com/doc/2012-12-01/">
|
||||||
|
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
|
||||||
|
<subnetSet>
|
||||||
|
<item>
|
||||||
|
<subnetId>subnet-9d4a7b6c</subnetId>
|
||||||
|
<state>available</state>
|
||||||
|
<vpcId>vpc-1a2b3c4d</vpcId>
|
||||||
|
<cidrBlock>10.0.1.0/24</cidrBlock>
|
||||||
|
<availableIpAddressCount>250</availableIpAddressCount>
|
||||||
|
<availabilityZone>us-east-1a</availabilityZone>
|
||||||
|
<tagSet>
|
||||||
|
<item>
|
||||||
|
<key>Name</key>
|
||||||
|
<value>ec2-o</value>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<key>Empty</key>
|
||||||
|
<value />
|
||||||
|
</item>
|
||||||
|
</tagSet>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<subnetId>subnet-6e7f829e</subnetId>
|
||||||
|
<state>available</state>
|
||||||
|
<vpcId>vpc-1a2b3c4d</vpcId>
|
||||||
|
<cidrBlock>10.0.0.0/24</cidrBlock>
|
||||||
|
<availableIpAddressCount>250</availableIpAddressCount>
|
||||||
|
<availabilityZone>us-east-1a</availabilityZone>
|
||||||
|
<tagSet/>
|
||||||
|
|
||||||
|
</item>
|
||||||
|
</subnetSet>
|
||||||
|
</DescribeSubnetsResponse>
|
Loading…
Reference in New Issue