Add RouteTable API.

Limitations:
Does not contain support for VgwRoutePropagation.
This commit is contained in:
Geoff Macartney 2017-05-12 16:44:30 +01:00 committed by Ignasi Barrera
parent a9006288e8
commit b3d21f9652
31 changed files with 2214 additions and 9 deletions

View File

@ -24,6 +24,7 @@ import org.jclouds.aws.ec2.features.AWSSubnetApi;
import org.jclouds.aws.ec2.features.InternetGatewayApi;
import org.jclouds.aws.ec2.features.MonitoringApi;
import org.jclouds.aws.ec2.features.PlacementGroupApi;
import org.jclouds.aws.ec2.features.RouteTableApi;
import org.jclouds.aws.ec2.features.SpotInstanceApi;
import org.jclouds.aws.ec2.features.VPCApi;
import org.jclouds.ec2.EC2Api;
@ -142,10 +143,24 @@ public interface AWSEC2Api extends EC2Api {
Optional<? extends InternetGatewayApi> getInternetGatewayApi();
/**
* Provides synchronous access to InternetGateway services in a given region.
* Provides synchronous access to Internet Gateway services in a given region.
*/
@Delegate
Optional<? extends InternetGatewayApi> getInternetGatewayApiForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region
);
/**
* Provides synchronous access to Route Table services.
*/
@Delegate
Optional<? extends RouteTableApi> getRouteTableApi();
/**
* Provides synchronous access to Route Table services in a given region.
*/
@Delegate
Optional<? extends RouteTableApi> getRouteTableApiForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region
);
}

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.binders;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the String [] to form parameters named with RouteTableId.index
*/
public class BindRouteTableIdsToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return AWSUtils.indexStringArrayToFormValuesWithPrefix(request, "RouteTableId", input);
}
}

View File

@ -0,0 +1,107 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.domain;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
/**
* A route in an Amazon EC2 Route Table.
*
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Route.html" >doc</a>
*/
@AutoValue
public abstract class Route {
public enum RouteState {
/**
* An active route.
*/
ACTIVE,
/**
* Indicates that the route's target isn't available (for example, the specified gateway isn't attached
* to the VPC, or the specified NAT instance has been terminated).
*/
BLACKHOLE,
/**
* Value supplied was not valid.
*/
UNRECOGNIZED;
public String value() {
return name().toLowerCase();
}
public static RouteState fromValue(String v) {
if (v == null || v.isEmpty()) {
throw new IllegalArgumentException("Value cannot be null or empty");
}
try {
return valueOf(v.toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
@Nullable
public abstract String destinationCidrBlock();
@Nullable
public abstract String gatewayId();
@Nullable
public abstract RouteState state();
@Nullable
public abstract String origin();
@SerializedNames({"destinationCidrBlock", "gatewayId", "state", "origin"})
public static Route create(String destinationCidrBlock, String gatewayId, RouteState state, String origin) {
return builder()
.destinationCidrBlock(destinationCidrBlock)
.gatewayId(gatewayId)
.state(state)
.origin(origin)
.build();
}
Route() {}
public static Builder builder() {
return new AutoValue_Route.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder destinationCidrBlock(String destinationCidrBlock);
public abstract Builder gatewayId(String gatewayId);
public abstract Builder state(RouteState state);
public abstract Builder origin(String origin);
public abstract Route build();
}
}

View File

@ -0,0 +1,99 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.domain;
import java.util.List;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* Amazon EC2 Route Table.
*
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RouteTable.html" >doc</a>
*/
@AutoValue
public abstract class RouteTable {
@Nullable
public abstract String id();
@Nullable
public abstract String vpcId();
@Nullable
public abstract List<Route> routeSet();
@Nullable
public abstract List<RouteTableAssociation> associationSet();
@Nullable
public abstract Map<String, String> tags();
@SerializedNames({"routeTableId", "vpcId", "routeSet", "associationSet", "tagSet"})
public static RouteTable create(String id,
String vpcId,
List<Route> routeSet,
List<RouteTableAssociation> associationSet,
Map<String, String> tags) {
return builder()
.id(id)
.vpcId(vpcId)
.routeSet(routeSet)
.associationSet(associationSet)
.tags(tags)
.build();
}
RouteTable() {}
public static Builder builder() {
return new AutoValue_RouteTable.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder id(String id);
public abstract Builder vpcId(String vpcId);
public abstract Builder routeSet(List<Route> routeSet);
public abstract Builder associationSet(List<RouteTableAssociation> associationSet);
public abstract Builder tags(Map<String, String> tags);
@Nullable abstract List<Route> routeSet();
@Nullable abstract List<RouteTableAssociation> associationSet();
@Nullable abstract Map<String, String> tags();
abstract RouteTable autoBuild();
public RouteTable build() {
routeSet(routeSet() != null ? ImmutableList.copyOf(routeSet()) : ImmutableList.<Route>of());
associationSet(associationSet() != null
? ImmutableList.copyOf(associationSet())
: ImmutableList.<RouteTableAssociation>of());
tags(tags() != null ? ImmutableMap.copyOf(tags()) : ImmutableMap.<String, String>of());
return autoBuild();
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.domain;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
import com.google.auto.value.AutoValue;
/**
* An association of a route to a subnet.
*
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RouteTableAssociation.html">AWS docs</a>
*/
@AutoValue
public abstract class RouteTableAssociation {
@Nullable
public abstract String id();
@Nullable
public abstract String routeTableId();
@Nullable
public abstract String subnetId();
@Nullable
public abstract Boolean main();
@SerializedNames({"routeTableAssociationId", "routeTableId", "subnetId", "main"})
public static RouteTableAssociation create(String id, String routeTableId, String subnetId, Boolean main) {
return builder()
.id(id)
.routeTableId(routeTableId)
.subnetId(subnetId)
.main(main)
.build();
}
RouteTableAssociation() {}
public static Builder builder() {
return new AutoValue_RouteTableAssociation.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder id(String id);
public abstract Builder routeTableId(String routeTableId);
public abstract Builder subnetId(String subnetId);
public abstract Builder main(Boolean main);
public abstract RouteTableAssociation build();
}
}

View File

@ -0,0 +1,279 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.features;
import static org.jclouds.aws.reference.FormParameters.ACTION;
import javax.inject.Named;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.Fallbacks;
import org.jclouds.aws.ec2.binders.BindRouteTableIdsToIndexedFormParams;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.aws.ec2.options.RouteOptions;
import org.jclouds.aws.ec2.options.RouteTableOptions;
import org.jclouds.aws.ec2.xml.AssociateRouteTableResponseHandler;
import org.jclouds.aws.ec2.xml.CreateRouteTableResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeRouteTablesResponseHandler;
import org.jclouds.aws.ec2.xml.ReturnValueHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.collect.FluentIterable;
/**
* Provides access to AWS Route Table services.
*
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RouteTable.html">RouteTable docs</a>
*/
@RequestFilters(FormSigner.class)
@VirtualHost
@Path("/")
public interface RouteTableApi {
/**
* Creates a {@link RouteTable}
*
* @param region The region to create the table in.
* @param vpcId The ID of the VPC
* @return The route table
*/
@Named("CreateRouteTable")
@POST
@FormParams(keys = ACTION, values = "CreateRouteTable")
@XMLResponseParser(CreateRouteTableResponseHandler.class)
RouteTable createRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("VpcId") String vpcId);
/**
* Creates a {@link RouteTable}, supplying options.
*
* @param region The region to create the table in
* @param vpcId The ID of the VPC
* @param options Options for the request
* @return The route table
*/
@Named("CreateRouteTable")
@POST
@FormParams(keys = ACTION, values = "CreateRouteTable")
@XMLResponseParser(CreateRouteTableResponseHandler.class)
RouteTable createRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("VpcId") String vpcId,
RouteTableOptions options);
/**
* Deletes a {@link RouteTable}
*
* @param region The region to delete the table from
* @param routeTableId The ID of the table to delete
* @return true if the route table was found and deleted
*/
@Named("DeleteRouteTable")
@POST
@FormParams(keys = ACTION, values = "DeleteRouteTable")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean deleteRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId);
/**
* Delete a {@link RouteTable}, supplying options.
*
* @param region The region to delete the table from
* @param routeTableId The ID of the table to delete
* @param options Options for the request
* @return true if the route table was found and deleted
*/
@Named("DeleteRouteTable")
@POST
@FormParams(keys = ACTION, values = "DeleteRouteTable")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean deleteRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
RouteTableOptions options);
/**
* Associates a subnet with a route table. The subnet and route table must be in the same VPC.
* This association causes traffic originating from the subnet to be routed according to the routes in the route table.
* The action returns an association ID, which you need in order to disassociate the route table from the subnet later.
* A route table can be associated with multiple subnets.
*
* @param region Region of the VPC for the route table
* @param routeTableId ID of the route table
* @param subnetId ID of the subnet to associate
*
* @return The association ID which you need in order to disassociate the route table from the subnet later.
*/
@Named("AssociateRouteTable")
@POST
@FormParams(keys = ACTION, values = "AssociateRouteTable")
@XMLResponseParser(AssociateRouteTableResponseHandler.class)
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
String associateRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
@FormParam("SubnetId") String subnetId);
/**
* @see #associateRouteTable(java.lang.String, java.lang.String, java.lang.String)
*
* @param region Region of the VPC for the route table
* @param routeTableId ID of the route table
* @param subnetId ID of the subnet to associate
* @param options Options for the request
*
* @return The association ID which you need in order to disassociate the route table from the subnet later.
*/
@Named("AssociateRouteTable")
@POST
@FormParams(keys = ACTION, values = "AssociateRouteTable")
@XMLResponseParser(AssociateRouteTableResponseHandler.class)
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
String associateRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
@FormParam("SubnetId") String subnetId,
RouteTableOptions options);
/**
* Disassociates a subnet from a route table.
* After you perform this action, the subnet no longer uses the routes in the route table.
* Instead, it uses the routes in the VPC's main route table.
* @param region Region of the route table
* @param associationId association id returned by {@link #associateRouteTable(String, String, String)}
* @return true if the subnet was found and disassociated.
*/
@Named("DisassociateRouteTable")
@POST
@FormParams(keys = ACTION, values = "DisassociateRouteTable")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean disassociateRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("AssociationId") String associationId);
/**
* @see #disassociateRouteTable(String, String)
* @param region Region of the route table
* @param associationId association id returned by {@link #associateRouteTable(String, String, String)}
* @param options Options for the request
* @return true if the subnet was found and disassociated.
*/
@Named("DisassociateRouteTable")
@POST
@FormParams(keys = ACTION, values = "DisassociateRouteTable")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean disassociateRouteTable(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("AssociationId") String associationId,
RouteTableOptions options);
/**
* Creates a route in a route table within a VPC.
*
* @param region region of the VPC
* @param routeTableId ID of the route table to put the route in
* @param options You must specify one of the following targets: Internet gateway or virtual
* private gateway, NAT instance, NAT gateway, VPC peering connection,
* network interface, or egress-only Internet gateway.
* @return true if the route was created
*/
@Named("CreateRoute")
@POST
@FormParams(keys = ACTION, values = "CreateRoute")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean createRoute(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
RouteOptions options);
/**
* Replaces a route in a route table within a VPC.
*
* @param region region of the VPC
* @param routeTableId ID of the route table containing the route to replace
* @param options You must specify only one of the following targets: Internet gateway or virtual
* private gateway, NAT instance, NAT gateway, VPC peering connection,
* network interface, or egress-only Internet gateway.
* @return true if the route was found and replaced
*/
@Named("ReplaceRoute")
@POST
@FormParams(keys = ACTION, values = "ReplaceRoute")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean replaceRoute(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
RouteOptions options);
/**
* Delete a route from a route table.
*
* @param region region of the VPC
* @param routeTableId ID of the route table owning the route
* @param options This should include the destination CIDR block of the route to delete
*
* @return true if the route was found and deleted
*
* <p>
* <b>Example:</b>
* <pre>
* api.deleteRoute(region, routeTable.id(), destinationCidrBlock("10.20.30.0/24"))
* </pre>
* </p>
*/
@Named("DeleteRoute")
@POST
@FormParams(keys = ACTION, values = "DeleteRoute")
@XMLResponseParser(ReturnValueHandler.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
boolean deleteRoute(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("RouteTableId") String routeTableId,
RouteOptions options);
/**
* Describes route tables.
* @param region The region to search for route tables.
*/
@Named("DescribeRouteTables")
@POST
@FormParams(keys = ACTION, values = "DescribeRouteTables")
@XMLResponseParser(DescribeRouteTablesResponseHandler.class)
@Fallback(Fallbacks.EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<RouteTable> describeRouteTables(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindRouteTableIdsToIndexedFormParams.class) String... routeTableIds);
}

View File

@ -28,7 +28,7 @@ import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
* import static org.jclouds.ec2.options.InternetGatewayOptions.Builder.*
* <p/>
* EC2Api connection = // get connection
* Future<Set<ImageMetadata>> images =
* InternetGateway gw =
* connection.getInternetGatewayApi().get().createInternetGateway(region, dryRun());
* <code>
*
@ -41,7 +41,8 @@ public class InternetGatewayOptions extends BaseEC2RequestOptions {
public static final InternetGatewayOptions NONE = new InternetGatewayOptions();
/**
* Checks whether you have the required permissions for the action, without actually making the request, and provides an error response.
* Checks whether you have the required permissions for the action, without actually making the request,
* and provides an error response.
*/
public InternetGatewayOptions dryRun() {
formParameters.put("DryRun", "true");

View File

@ -0,0 +1,254 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the Route operations. <h2>
* Usage</h2> The recommended way to instantiate such an object is to statically import
* RouteOptions.Builder.* and invoke a static creation method followed by an instance mutator
* (if needed):
* <p/>
* <code>
* import static org.jclouds.ec2.options.RouteOptions.Builder.*
* <p/>
* EC2Api connection = // get connection
* Route r = connection.getRouteTableApi().get()
* .createRoute(region, routeTableId, gatewayId("igw-97e68af3").destinationCidrBlock("172.18.19.0/24"));
* <code>
*
* @see <a
* href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateRoute.html"
* />
*/
public class RouteOptions extends BaseEC2RequestOptions {
/**
* Checks whether you have the required permissions for the action, without actually making the request,
* and provides an error response.
*/
public RouteOptions dryRun() {
formParameters.put("DryRun", "true");
return this;
}
public boolean isDryRun() {
return getFirstFormOrNull("DryRun") != null;
}
/**
* The IPv4 CIDR address block used for the destination match.
* Routing decisions are based on the most specific match.
*/
public RouteOptions destinationCidrBlock(String destinationCidrBlock) {
formParameters.put("DestinationCidrBlock", checkNotNull(destinationCidrBlock, "destinationCidrBlock"));
return this;
}
/**
* @see RouteOptions#destinationCidrBlock(java.lang.String)
*/
public String getDestinationCidrBlock() {
return getFirstFormOrNull("DestinationCidrBlock");
}
/**
* The IPv6 CIDR block used for the destination match. Routing decisions are based on the most specific match.
*/
public RouteOptions destinationIpv6CidrBlock(String destinationIpv6CidrBlock) {
formParameters.put("DestinationIpv6CidrBlock", checkNotNull(destinationIpv6CidrBlock, "destinationIpv6CidrBlock"));
return this;
}
/**
* @see RouteOptions#destinationIpv6CidrBlock(java.lang.String)
*/
public String getDestinationIpv6CidrBlock() {
return getFirstFormOrNull("DestinationIpv6CidrBlock");
}
/**
* The ID of an Internet gateway or virtual private gateway attached to your VPC.
*/
public RouteOptions gatewayId(String gatewayId) {
formParameters.put("GatewayId", checkNotNull(gatewayId, "gatewayId"));
return this;
}
/**
* @see RouteOptions#gatewayId(java.lang.String)
*/
public String getGatewayId() {
return getFirstFormOrNull("GatewayId");
}
/**
* [IPv6 traffic only] The ID of an egress-only Internet gateway.
*/
public RouteOptions egressOnlyInternetGatewayId(String egressOnlyInternetGatewayId) {
formParameters.put("EgressOnlyInternetGatewayId",
checkNotNull(egressOnlyInternetGatewayId, "egressOnlyInternetGatewayId"));
return this;
}
/**
* @see RouteOptions#egressOnlyInternetGatewayId(java.lang.String)
*/
public String getEgressOnlyInternetGatewayId() {
return getFirstFormOrNull("EgressOnlyInternetGatewayId");
}
/**
* [IPv4 traffic only] The ID of a NAT gateway.
*/
public RouteOptions natGatewayId(String natGatewayId) {
formParameters.put("NatGatewayId", checkNotNull(natGatewayId, "natGatewayId"));
return this;
}
/**
* @see RouteOptions#natGatewayId(String)
*/
public String getNatGatewayId() {
return getFirstFormOrNull("NatGatewayId");
}
/**
* The ID of a network interface.
*/
public RouteOptions networkInterfaceId(String networkInterfaceId) {
formParameters.put("NetworkInterfaceId", checkNotNull(networkInterfaceId, "networkInterfaceId"));
return this;
}
/**
* @see RouteOptions#networkInterfaceId(String)
*/
public String getNetworkInterfaceId() {
return getFirstFormOrNull("NetworkInterfaceId");
}
/**
* The ID of a NAT instance in your VPC. The operation fails if you specify an instance ID unless
* exactly one network interface is attached.
*/
public RouteOptions instanceId(String instanceId) {
formParameters.put("InstanceId", checkNotNull(instanceId, "instanceId"));
return this;
}
/**
* @see RouteOptions#instanceId(String)
*/
public String getInstanceId() {
return getFirstFormOrNull("InstanceId");
}
/**
* The ID of a VPC peering connection.
*/
public RouteOptions vpcPeeringConnectionId(String vpcPeeringConnectionId) {
formParameters.put("VpcPeeringConnectionId", checkNotNull(vpcPeeringConnectionId, "vpcPeeringConnectionId"));
return this;
}
/**
* @see RouteOptions#vpcPeeringConnectionId(String)
*/
public String getVpcPeeringConnectionId() {
return getFirstFormOrNull("VpcPeeringConnectionId");
}
public static class Builder {
/**
* @see RouteOptions#dryRun()
*/
public static RouteOptions dryRun() {
RouteOptions options = new RouteOptions();
return options.dryRun();
}
/**
* @see RouteOptions#destinationCidrBlock(java.lang.String)
*/
public static RouteOptions destinationCidrBlock(String destinationCidrBlock) {
RouteOptions options = new RouteOptions();
return options.destinationCidrBlock(destinationCidrBlock);
}
/**
* @see RouteOptions#destinationIpv6CidrBlock(java.lang.String)
*/
public static RouteOptions destinationIpv6CidrBlock(String destinationIpv6CidrBlock) {
RouteOptions options = new RouteOptions();
return options.destinationIpv6CidrBlock(destinationIpv6CidrBlock);
}
/**
* @see RouteOptions#gatewayId(java.lang.String)
*/
public static RouteOptions gatewayId(String gatewayId) {
RouteOptions options = new RouteOptions();
return options.gatewayId(gatewayId);
}
/**
* @see RouteOptions#egressOnlyInternetGatewayId(java.lang.String)
*/
public static RouteOptions egressOnlyInternetGatewayId(String egressOnlyInternetGatewayId) {
RouteOptions options = new RouteOptions();
return options.egressOnlyInternetGatewayId(egressOnlyInternetGatewayId);
}
/**
* @see RouteOptions#natGatewayId(String)
*/
public static RouteOptions natGatewayId(String natGatewayId) {
RouteOptions options = new RouteOptions();
return options.natGatewayId(natGatewayId);
}
/**
* @see RouteOptions#networkInterfaceId(String)
*/
public static RouteOptions networkInterfaceId(String networkInterfaceId) {
RouteOptions options = new RouteOptions();
return options.networkInterfaceId(networkInterfaceId);
}
/**
* @see RouteOptions#vpcPeeringConnectionId(String)
*/
public static RouteOptions vpcPeeringConnectionId(String vpcPeeringConnectionId) {
RouteOptions options = new RouteOptions();
return options.vpcPeeringConnectionId(vpcPeeringConnectionId);
}
/**
* @see RouteOptions#instanceId(String)
*/
public static RouteOptions instanceId(String instanceId) {
RouteOptions options = new RouteOptions();
return options.instanceId(instanceId);
}
}
}

View File

@ -0,0 +1,75 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.ec2.options.internal.BaseEC2RequestOptions;
/**
* Contains options supported in the Form API for the RouteTable operations. <h2>
* Usage</h2> The recommended way to instantiate such an object is to statically import
* RouteTableOptions.Builder.* and invoke a static creation method followed by an instance mutator
* (if needed):
* <p/>
* <code>
* import static org.jclouds.ec2.options.RouteTableOptions.Builder.*
* <p/>
* EC2Api connection = // get connection
* RouteTable table = connection.getRouteTableApi().get().createRouteTable(vpcId, dryRun());
* <code>
*
* @see <a
* href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateRouteTable.html"
* />
*/
public class RouteTableOptions extends BaseEC2RequestOptions {
/**
* Checks whether you have the required permissions for the action, without actually making the request,
* and provides an error response.
*/
public RouteTableOptions dryRun() {
formParameters.put("DryRun", "true");
return this;
}
public boolean isDryRun() {
return getFirstFormOrNull("DryRun") != null;
}
/**
* The IPv4 CIDR address block used for the destination match.
* Routing decisions are based on the most specific match.
*/
public RouteTableOptions destinationCidrBlock(String destinationCidrBlock) {
formParameters.put("DestinationCidrBlock", checkNotNull(destinationCidrBlock, "destinationCidrBlock"));
return this;
}
public static class Builder {
/**
* @see RouteTableOptions#dryRun()
*/
public static RouteTableOptions dryRun() {
RouteTableOptions options = new RouteTableOptions();
return options.dryRun();
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import org.jclouds.http.functions.ParseSax;
public class AssociateRouteTableResponseHandler extends ParseSax.HandlerWithResult<String> {
private StringBuilder currentText = new StringBuilder();
private String value;
public String getResult() {
return value;
}
public void endElement(String uri, String name, String qName) {
if (qName.equalsIgnoreCase("associationId")) {
this.value = currentText.toString().trim();
}
currentText.setLength(0);
}
public void characters(char[] ch, int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
/**
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RouteTable.html">RouteTable docs</a>
*/
public class CreateRouteTableResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<RouteTable> {
private RouteTableHandler routeTableHandler;
@Inject
CreateRouteTableResponseHandler(RouteTableHandler routeTableHandler) {
this.routeTableHandler = routeTableHandler;
}
public RouteTable getResult() {
return routeTableHandler.getResult();
}
@Override
public void startElement(String uri, String name, String qName, Attributes attrs) {
routeTableHandler.startElement(uri, name, qName, attrs);
}
@Override
public void endElement(String uri, String name, String qName) {
routeTableHandler.endElement(uri, name, qName);
}
@Override
public void characters(char[] ch, int start, int length) {
routeTableHandler.characters(ch, start, length);
}
}

View File

@ -0,0 +1,100 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.List;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
/**
* @see <a href="http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RouteTable.html">RouteTable docs</a>
*/
public class DescribeRouteTablesResponseHandler
extends ParseSax.HandlerForGeneratedRequestWithResult<FluentIterable<RouteTable>> {
private RouteTableHandler routeTableHandler;
private List<RouteTable> tables = Lists.newArrayList();
private boolean inRouteSet;
private boolean inAssociationSet;
private boolean inPropagatingVgwSet;
private boolean inTagSet;
@Inject
DescribeRouteTablesResponseHandler(RouteTableHandler routeTableHandler) {
this.routeTableHandler = routeTableHandler;
}
public FluentIterable<RouteTable> getResult() {
try {
return FluentIterable.from(tables);
} finally {
tables = Lists.newArrayList();
}
}
@Override
public void startElement(String uri, String name, String qName, Attributes attrs) {
if (equalsOrSuffix(qName, "routeSet")) {
inRouteSet = true;
} else if (equalsOrSuffix(qName, "associationSet")) {
inAssociationSet = true;
} else if (equalsOrSuffix(qName, "tagSet")) {
inTagSet = true;
} else if (equalsOrSuffix(qName, "propagatingVgwSet")) {
inPropagatingVgwSet = true;
}
routeTableHandler.startElement(uri, name, qName, attrs);
}
private boolean inSubElement() {
return inRouteSet || inTagSet || inAssociationSet || inPropagatingVgwSet;
}
@Override
public void endElement(String uri, String name, String qName) {
if (equalsOrSuffix(qName, "routeSet")) {
inRouteSet = false;
routeTableHandler.endElement(uri, name, qName);
} else if (equalsOrSuffix(qName, "associationSet")) {
inAssociationSet = false;
routeTableHandler.endElement(uri, name, qName);
} else if (equalsOrSuffix(qName, "tagSet")) {
inTagSet = false;
routeTableHandler.endElement(uri, name, qName);
} else if (equalsOrSuffix(qName, "item") && !inSubElement()) {
final RouteTable table = routeTableHandler.getResult();
tables.add(table);
} else {
routeTableHandler.endElement(uri, name, qName);
}
}
@Override
public void characters(char[] ch, int start, int length) {
routeTableHandler.characters(ch, start, length);
}
}

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import org.jclouds.aws.ec2.domain.Route;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
public class RouteHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Route> {
private StringBuilder currentText = new StringBuilder();
Route.Builder builder = Route.builder();
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
}
@Override
public void endElement(String uri, String localName, String qName) {
}
@Override
public void characters(char[] ch, int start, int length) {
currentText.append(ch, start, length);
}
@Override
public Route getResult() {
return builder.build();
}
}

View File

@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.List;
import org.jclouds.aws.ec2.domain.Route;
import org.jclouds.aws.ec2.domain.Route.RouteState;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import com.google.common.collect.Lists;
public class RouteSetHandler extends ParseSax.HandlerForGeneratedRequestWithResult<List<Route>> {
private StringBuilder currentText = new StringBuilder();
List<Route> results = Lists.newArrayList();
Route.Builder builder;
@Override
public List<Route> getResult() {
try {
return results;
} finally {
results = Lists.newArrayList();
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
currentText.setLength(0);
if (qName.equalsIgnoreCase("item")) {
builder = Route.builder();
}
}
@Override
public void endElement(String uri, String name, String qName) {
if (builder == null) {
return;
}
if (equalsOrSuffix(qName, "item")) {
results.add(builder.build());
builder = null;
} else if (equalsOrSuffix(qName, "destinationCidrBlock")) {
builder.destinationCidrBlock(currentText.toString());
} else if (equalsOrSuffix(qName, "gatewayId")) {
builder.gatewayId(currentText.toString());
} else if (equalsOrSuffix(qName, "state")) {
builder.state(RouteState.fromValue(currentText.toString()));
} else if (equalsOrSuffix(qName, "origin")) {
builder.origin(currentText.toString());
}
}
@Override
public void characters(char[] ch, int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.List;
import org.jclouds.aws.ec2.domain.RouteTableAssociation;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import com.google.common.collect.Lists;
public class RouteTableAssociationSetHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<List<RouteTableAssociation>> {
private StringBuilder currentText = new StringBuilder();
RouteTableAssociation.Builder builder;
List<RouteTableAssociation> results = Lists.newArrayList();
@Override
public List<RouteTableAssociation> getResult() {
try {
return results;
} finally {
results = Lists.newArrayList();
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
currentText.setLength(0);
if (qName.equalsIgnoreCase("item")) {
builder = RouteTableAssociation.builder();
}
}
@Override
public void endElement(String uri, String name, String qName) {
if (builder == null) {
return;
}
if (equalsOrSuffix(qName, "item")) {
results.add(builder.build());
builder = null;
} else if (equalsOrSuffix(qName, "routeTableAssociationId")) {
builder.id(currentText.toString());
} else if (equalsOrSuffix(qName, "routeTableId")) {
builder.routeTableId(currentText.toString());
} else if (equalsOrSuffix(qName, "subnetId")) {
builder.subnetId(currentText.toString());
} else if (equalsOrSuffix(qName, "main")) {
builder.main(Boolean.valueOf(currentText.toString()));
}
}
@Override
public void characters (char[] ch, int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,116 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.ec2.xml.TagSetHandler;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
public class RouteTableHandler extends ParseSax.HandlerWithResult<RouteTable> {
RouteTable.Builder builder = RouteTable.builder();
private StringBuilder currentText = new StringBuilder();
private RouteSetHandler routeSetHandler;
private RouteTableAssociationSetHandler routeTableAssociationSetHandler;
private TagSetHandler tagSetHandler;
boolean inRouteSet;
boolean inRouteTableAssociationSet;
boolean inTagSet;
// TODO propagatingVgwSetHandler
@Inject
RouteTableHandler(TagSetHandler tagSetHandler, RouteSetHandler routeSetHandler,
RouteTableAssociationSetHandler routeTableAssociationSetHandler) {
this.tagSetHandler = tagSetHandler;
this.routeSetHandler = routeSetHandler;
this.routeTableAssociationSetHandler = routeTableAssociationSetHandler;
}
@Override
public RouteTable getResult() {
try {
return builder.build();
} finally {
builder = RouteTable.builder();
}
}
@Override
public void startElement(String uri, String name, String qName, Attributes attrs) {
currentText.setLength(0);
if (equalsOrSuffix(qName, "routeSet")) {
inRouteSet = true;
} else if (equalsOrSuffix(qName, "associationSet")) {
inRouteTableAssociationSet = true;
} else if (equalsOrSuffix(qName, "tagSet")) {
inTagSet = true;
}
if (inTagSet) {
tagSetHandler.startElement(uri, name, qName, attrs);
} else if (inRouteTableAssociationSet) {
routeTableAssociationSetHandler.startElement(uri, name, qName, attrs);
} else if (inRouteSet) {
routeSetHandler.startElement(uri, name, qName, attrs);
}
}
@Override
public void endElement(String uri, String name, String qName) {
if (equalsOrSuffix(qName, "tagSet")) {
inTagSet = false;
builder.tags(tagSetHandler.getResult());
} else if (equalsOrSuffix(qName, "routeSet")) {
inRouteSet = false;
builder.routeSet(routeSetHandler.getResult());
} else if (equalsOrSuffix(qName, "associationSet")) {
inRouteTableAssociationSet = false;
builder.associationSet(routeTableAssociationSetHandler.getResult());
} else if (inRouteSet) {
routeSetHandler.endElement(uri, name, qName);
} else if (inRouteTableAssociationSet) {
routeTableAssociationSetHandler.endElement(uri, name, qName);
} else if (inTagSet) {
tagSetHandler.endElement(uri, name, qName);
} else if (equalsOrSuffix(qName, "vpcId")) {
builder.vpcId(currentText.toString());
} else if (equalsOrSuffix(qName, "routeTableId")) {
builder.id(currentText.toString());
}
currentText.setLength(0);
}
@Override
public void characters(char[] ch, int start, int length) {
if (inRouteSet) {
routeSetHandler.characters(ch, start, length);
} else if (inRouteTableAssociationSet) {
routeTableAssociationSetHandler.characters(ch, start, length);
} else if (inTagSet) {
tagSetHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -36,6 +36,7 @@ import org.jclouds.aws.ec2.domain.VPC;
import org.jclouds.aws.ec2.options.CreateVpcOptions;
import org.jclouds.aws.ec2.options.InternetGatewayOptions;
import org.jclouds.ec2.features.TagApi;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -49,7 +50,9 @@ import com.google.common.collect.ImmutableMap;
@Test(groups = "live")
public class InternetGatewayApiLiveTest extends BaseApiLiveTest<AWSEC2Api> {
private static final String TEST_REGION = "eu-west-1";
// Define -Djclouds.test.region=whatever to test in your preferred region;
// defaults to null, jclouds will pick the provider's default region
private static final String TEST_REGION = System.getProperty("jclouds.test.region");
public InternetGatewayApiLiveTest() {
provider = "aws-ec2";
@ -60,8 +63,8 @@ public class InternetGatewayApiLiveTest extends BaseApiLiveTest<AWSEC2Api> {
private VPCApi vpcClient;
private VPC vpc;
private InternetGateway gateway;
private String simpleName = InternetGatewayApiLiveTest.class.getSimpleName() + new Random().nextInt(10000);
@BeforeClass(groups = {"integration", "live"})
@ -149,6 +152,7 @@ public class InternetGatewayApiLiveTest extends BaseApiLiveTest<AWSEC2Api> {
try {
gwClient.createInternetGateway(TEST_REGION, dryRun());
Assert.fail("Operation completed when exception was expected");
} catch (AWSResponseException e) {
assertEquals(e.getError().getCode(), "DryRunOperation", "Expected DryRunOperation but got " + e.getError());
}

View File

@ -16,6 +16,7 @@
*/
package org.jclouds.aws.ec2.features;
import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED;
import static org.jclouds.aws.ec2.options.InternetGatewayOptions.Builder.dryRun;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@ -29,6 +30,7 @@ import org.jclouds.aws.ec2.domain.InternetGateway;
import org.jclouds.aws.ec2.domain.InternetGatewayAttachment;
import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest;
import org.jclouds.aws.ec2.options.InternetGatewayOptions;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.FluentIterable;
@ -164,7 +166,6 @@ public class InternetGatewayApiMockTest extends BaseAWSEC2ApiMockTest {
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DescribeInternetGateways");
}
public void deleteInternetGateway() throws Exception {
@ -193,18 +194,19 @@ public class InternetGatewayApiMockTest extends BaseAWSEC2ApiMockTest {
public void testWithOptions() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/create_internet_gateway_dry_run.xml");
enqueueXml(PRECONDITION_FAILED, DEFAULT_REGION, "/dry_run.xml");
try {
gatewayApi().createInternetGateway(DEFAULT_REGION, dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertEquals(e.getError().getCode(), "DryRunOperation", "Expected DryRunOperation but got " + e.getError());
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=CreateInternetGateway&DryRun=true");
}
private InternetGatewayApi gatewayApi() {
return api().getInternetGatewayApi().get();
}

View File

@ -0,0 +1,293 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.features;
import static java.util.logging.Logger.getAnonymousLogger;
import static org.jclouds.aws.ec2.options.RouteOptions.Builder.destinationCidrBlock;
import static org.jclouds.aws.ec2.options.RouteOptions.Builder.gatewayId;
import static org.jclouds.aws.ec2.options.RouteTableOptions.Builder.dryRun;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.List;
import java.util.Random;
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.ec2.AWSEC2Api;
import org.jclouds.aws.ec2.domain.InternetGateway;
import org.jclouds.aws.ec2.domain.Route;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.aws.ec2.domain.VPC;
import org.jclouds.aws.ec2.options.InternetGatewayOptions;
import org.jclouds.ec2.domain.Subnet;
import org.jclouds.ec2.features.TagApi;
import org.testng.Assert;
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.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
/**
* Tests behavior of {@link RouteTableApi}
*/
@Test(groups = "live")
public class RouteTableApiLiveTest extends BaseApiLiveTest<AWSEC2Api> {
// Define -Djclouds.test.region=whatever to test in your preferred region;
// defaults to null, jclouds will pick the provider's default region
public static final String TEST_REGION = System.getProperty("jclouds.test.region");
public static final String TEST_DESTINATION_CIDR = "172.18.19.0/24";
public static final String VPC_CIDR = "10.20.30.0/24";
public static final String VPC_SUBNET = "10.20.30.0/28";
public RouteTableApiLiveTest() {
provider = "aws-ec2";
}
private RouteTableApi routeTableApi;
private InternetGatewayApi gwApi;
private TagApi tagger;
private VPCApi vpcClient;
private AWSSubnetApi subnetApi;
private VPC vpc;
private InternetGateway gateway;
private RouteTable routeTable;
private String associationId;
private Subnet subnet;
private String simpleName = RouteTableApiLiveTest.class.getSimpleName() + new Random().nextInt(10000);
@BeforeClass(groups = {"integration", "live"})
public void setupContext() {
routeTableApi = api.getRouteTableApiForRegion(TEST_REGION).get();
vpcClient = api.getVPCApi().get();
tagger = api.getTagApiForRegion(TEST_REGION).get();
gwApi = api.getInternetGatewayApiForRegion(TEST_REGION).get();
subnetApi = api.getAWSSubnetApi().get();
}
@Test
public void testDescribe() {
vpc = vpcClient.createVpc(TEST_REGION, VPC_CIDR);
assertNotNull(vpc, "Failed to create VPC to test attachments");
tagger.applyToResources(ImmutableMap.of("Name", simpleName), ImmutableList.of(vpc.id()));
// When you create a VPC it automatically gets a route table whose single route has the CIDR of the VPC
// and whose "target" is "local".
final FluentIterable<RouteTable> routeTables = routeTableApi.describeRouteTables(TEST_REGION);
assertNotNull(routeTables, "Failed to return list of RouteTables");
Optional<RouteTable> vpcRT = Iterables.tryFind(routeTables, new Predicate<RouteTable>() {
@Override public boolean apply(RouteTable input) {
return vpc.id().equals(input.vpcId());
}
});
assertTrue(vpcRT.isPresent(), "Could not find VPC " + vpc.id() + " in described route tables");
RouteTable rt = vpcRT.get();
assertEquals(rt.associationSet().size(), 1,
"Route for test VPC has wrong number of associations, should be 1: " + rt.associationSet());
assertTrue(rt.associationSet().get(0).main(), "Association for route " + rt.id() + "should be 'main'");
assertEquals(rt.routeSet().size(), 1,
"Wrong number of routes in default route table for VPC " + vpc.id());
final String defaultCidr = rt.routeSet().get(0).destinationCidrBlock();
assertEquals(defaultCidr, vpc.cidrBlock(),
"Route in default route table does not match CIDR of VPC, " + defaultCidr + " should be " + vpc.cidrBlock());
}
@Test(dependsOnMethods = "testDescribe")
public void testCreate() {
// When you create a new route table for the VPC it automatically gets a route to match the VPC CIDR
routeTable = routeTableApi.createRouteTable(TEST_REGION, vpc.id());
assertNotNull(routeTable, "Gateway was not successfully created");
assertEquals(routeTable.vpcId(), vpc.id(),
"RouteTable VPC ID " + routeTable.vpcId() + " does not match VPC's ID " + vpc.id());
final List<Route> routes = routeTable.routeSet();
assertEquals(routes.size(), 1, "Unexpected number of routes in new table: " + routes.size());
assertEquals(routes.get(0).destinationCidrBlock(), vpc.cidrBlock(),
"CIDR for route table " + routes.get(0).destinationCidrBlock() +
" does not match VPC CIDR" + vpc.cidrBlock());
assertEquals(routes.get(0).state(), Route.RouteState.ACTIVE, "Route should be active");
assertEquals(routeTable.tags().size(), 0, "Freshly created routeTable has tags");
tagger.applyToResources(ImmutableMap.of("Name", simpleName), ImmutableList.of(routeTable.id()));
getAnonymousLogger().info("Created routeTable " + simpleName + " with id " + routeTable.id());
}
@Test(dependsOnMethods = "testDescribe")
public void testCreateWithOptions() {
try {
routeTableApi.createRouteTable(TEST_REGION, vpc.id(), dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
}
@Test(dependsOnMethods = "testCreate")
public void testAssociateWithOptions() {
subnet = subnetApi.createSubnetInRegion(TEST_REGION, vpc.id(), VPC_SUBNET);
assertNotNull(subnet, "Failed to create subnet in " + vpc.id());
try {
routeTableApi.associateRouteTable(TEST_REGION, routeTable.id(), subnet.getSubnetId(), dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
}
@Test(dependsOnMethods = "testAssociateWithOptions")
public void testAssociate() {
associationId = routeTableApi.associateRouteTable(TEST_REGION, routeTable.id(), subnet.getSubnetId());
assertNotNull(associationId,
"Failed to obtain association id for " + routeTable.id() + " and " + subnet.getSubnetId());
routeTable = routeTableApi.describeRouteTables(TEST_REGION, routeTable.id()).toList().get(0);
assertEquals(routeTable.associationSet().size(), 1,
"Could not find expected association in routeTable " + routeTable.id());
}
@Test(dependsOnMethods = "testAssociate")
public void testDisassociateWithOptions() {
try {
routeTableApi.disassociateRouteTable(TEST_REGION, associationId, dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
}
@Test(dependsOnMethods = "testDisassociateWithOptions")
public void testDisassociate() {
final boolean result = routeTableApi.disassociateRouteTable(TEST_REGION, associationId);
assertTrue(result, "Failed to disassociate " + associationId + " from " + routeTable.id());
routeTable = routeTableApi.describeRouteTables(TEST_REGION, routeTable.id()).toList().get(0);
assertEquals(routeTable.associationSet().size(), 0,
"Found associations where none should exist in " + routeTable.id() + ": " + routeTable.associationSet());
subnetApi.deleteSubnetInRegion(TEST_REGION, subnet.getSubnetId());
}
@Test(dependsOnMethods = "testCreate")
public void testCreateRoute() {
// If you attach an Internet Gateway, Network Interface, or Virtual Private Gateway to the VPC
// you can then add a route through it to the route table. Issue a CreateRoute request specifying
// the gateway (or network interface id etc.) to route through, and supplying the CIDR range that should
// be routed through it. This can be any CIDR.
gateway = gwApi.createInternetGateway(TEST_REGION, InternetGatewayOptions.NONE);
assertNotNull(gateway, "Gateway was not successfully created");
final Boolean attached = gwApi.attachInternetGateway(TEST_REGION, gateway.id(), vpc.id());
assertTrue(attached, "Gateway " + gateway.id() + " failed to attach to VPC " + vpc.id());
final boolean created = routeTableApi.createRoute(TEST_REGION, routeTable.id(),
gatewayId(gateway.id())
.destinationCidrBlock(TEST_DESTINATION_CIDR));
assertTrue(created, "Failed to add route to table " + routeTable.id());
final ImmutableList<RouteTable> routeTables =
routeTableApi.describeRouteTables(TEST_REGION, routeTable.id()).toList();
assertEquals(routeTables.size(), 1, "Could not find existing route table " + routeTable.id());
Optional<Route> optRoute = Iterables.tryFind(routeTables.get(0).routeSet(), new Predicate<Route>() {
@Override
public boolean apply(Route route) {
return route.gatewayId().equals(gateway.id());
}
});
assertTrue(optRoute.isPresent(), "Could not find route added to gateway " + gateway.id());
Route route = optRoute.get();
assertEquals(route.destinationCidrBlock(), TEST_DESTINATION_CIDR,
"CIDR routed through " + gateway.id() + " does not match specification " + TEST_DESTINATION_CIDR);
}
@Test(dependsOnMethods = "testCreateRoute")
public void testDeleteRoute() {
final boolean deleted =
routeTableApi.deleteRoute(TEST_REGION, routeTable.id(), destinationCidrBlock(TEST_DESTINATION_CIDR));
assertTrue(deleted, "Failed to delete " + TEST_DESTINATION_CIDR + " route from route table " + routeTable.id());
// clean up the test gateway
final Boolean cleaned = gwApi.detachInternetGateway(TEST_REGION, gateway.id(), vpc.id());
assertTrue(cleaned, "Failed to delete gateway " + gateway.id());
final boolean gatewayDeleted = gwApi.deleteInternetGateway(TEST_REGION, gateway.id());
assertTrue(gatewayDeleted, "Failed to delete test gateway " + gateway.id());
}
@Test(enabled = false /* dependsOnMethods = "testCreateRoute" */)
public void testReplaceRoute() {
// TODO:
// At present there is support for creating internet gateways and attaching them to VPCs.
// However, you can't attach two internet gateways to the same VPC, so the replaceRoute test must replace
// the internet gateway target with one of an virtual private gateway, NAT instance,
// NAT gateway, VPC peering connection, network interface, or egress-only Internet gateway.
// Add this test when e.g. NATGatewayApi is added.
}
@Test(dependsOnMethods = "testDeleteRoute")
public void testDeleteRouteTableWithOptions() {
try {
routeTableApi.deleteRouteTable(TEST_REGION, routeTable.id(), dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
}
@Test(dependsOnMethods = "testDeleteRouteTableWithOptions")
public void testDeleteRouteTable() {
final ImmutableList<RouteTable> before =
routeTableApi.describeRouteTables(TEST_REGION, routeTable.id()).toList();
assertEquals(before.size(), 1, "Unexpected response to describe of " + routeTable.id() + ": " + before);
assertEquals(before.get(0).id(), routeTable.id(), "Wrong table returned for " + routeTable.id() + ": " + before);
final boolean deleted = routeTableApi.deleteRouteTable(TEST_REGION, routeTable.id());
assertTrue(deleted, "Failed to delete route table " + routeTable.id());
final ImmutableList<RouteTable> after = routeTableApi.describeRouteTables(TEST_REGION, routeTable.id()).toList();
assertEquals(after.size(), 0, "Unexpected response to describe after deleting " + routeTable.id() + ": " + after);
}
@AfterClass(alwaysRun = true)
public void cleanup() {
if (vpc != null) {
assertTrue(vpcClient.deleteVpc(TEST_REGION, vpc.id()));
}
}
private void assertDryRun(AWSResponseException e) {
assertEquals(e.getError().getCode(), "DryRunOperation", "Expected DryRunOperation but got " + e.getError());
}
}

View File

@ -0,0 +1,301 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.aws.ec2.features;
import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED;
import static org.jclouds.aws.ec2.options.RouteOptions.Builder.destinationCidrBlock;
import static org.jclouds.aws.ec2.options.RouteOptions.Builder.gatewayId;
import static org.jclouds.aws.ec2.options.RouteTableOptions.Builder.dryRun;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.ec2.domain.Route;
import org.jclouds.aws.ec2.domain.RouteTable;
import org.jclouds.aws.ec2.internal.BaseAWSEC2ApiMockTest;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.squareup.okhttp.mockwebserver.MockResponse;
@Test(groups = "unit", testName = "RouteTableApiMockTest", singleThreaded = true)
public class RouteTableApiMockTest extends BaseAWSEC2ApiMockTest {
public void describeRouteTables() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final ImmutableList<RouteTable> routeTables = routeTableApi().describeRouteTables(DEFAULT_REGION).toList();
assertTrue(routeTables.isEmpty(), "Returned " + routeTables.size() + " results for 404 response: " + routeTables);
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DescribeRouteTables");
}
public void describeRouteTablesNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/describe_route_tables.xml");
final ImmutableList<RouteTable> routeTables = routeTableApi().describeRouteTables(DEFAULT_REGION).toList();
assertNotNull(routeTables, "Failed to create route table description object");
assertEquals(routeTables.size(), 3, "Failed to return all entries from test data, returned: " + routeTables);
for (RouteTable table : routeTables) {
if (ImmutableList.of("rtb-80a3fae4", "rtb-d4605bb0").contains(table.id())) {
assertRoutesForNormalVpc(table, table.id());
} else if (table.id().equals("rtb-e6c98381")) {
assertRoutesForTestVpc(table, table.id());
}
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DescribeRouteTables");
}
public void describeRouteTablesWithInvalidStateValue() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/describe_route_tables_invalid.xml");
final ImmutableList<RouteTable> routeTables = routeTableApi().describeRouteTables(DEFAULT_REGION).toList();
assertNotNull(routeTables, "Failed to create route table description object");
assertEquals(routeTables.size(), 1, "Failed to return expected entry from test data, returned: " + routeTables);
assertEquals(routeTables.get(0).routeSet().get(0).state(), Route.RouteState.UNRECOGNIZED);
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DescribeRouteTables");
}
private void assertRoutesForNormalVpc(RouteTable table, String id) {
assertEquals(table.routeSet().size(), 2, "Failed to match test data route set size for " + id);
final String actual = table.associationSet().get(0).routeTableId();
assertEquals(actual, id, "Test data mismatch in " + id + " association set routeTableId(): " + actual);
assertTrue(table.associationSet().get(0).main(), "Test data mismatch in " + id + " association 'main'");
}
private void assertRoutesForTestVpc(RouteTable table, String id) {
assertEquals(table.routeSet().size(), 1, "Failed to match test data route set size for " + id);
assertEquals(table.routeSet().get(0).destinationCidrBlock(), "10.20.30.0/24",
"Mismatch in test data for " + id + " route set destinationCidrBlock");
assertEquals(table.routeSet().get(0).gatewayId(), "local",
"Mismatch in test data for " + id + " route set gatewayId");
assertEquals(table.routeSet().get(0).state(), Route.RouteState.ACTIVE,
"Mismatch in test data for " + id + " route set state");
final String actual = table.associationSet().get(0).routeTableId();
assertEquals(actual, id, "Test data mismatch in " + id + " association set routeTableId(): " + actual);
assertTrue(table.associationSet().get(0).main(), "Test data mismatch in " + id + " association 'main'");
}
public void createRouteTable() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/create_route_table.xml");
RouteTable result = routeTableApi().createRouteTable(DEFAULT_REGION, "vpc-1a2b3c4d");
assertNotNull(result, "Failed to create RouteTable object");
assertEquals(result.id(), "rtb-8bda6cef", "Gateway id does not match mock data: " + result.id());
assertEquals(result.routeSet().size(), 2, "Should have 2 routes");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=CreateRouteTable&VpcId=vpc-1a2b3c4d");
}
public void createRouteTableWithOptions() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(PRECONDITION_FAILED, DEFAULT_REGION, "/dry_run.xml");
try {
routeTableApi().createRouteTable(DEFAULT_REGION, "vpc-1a2b3c4d", dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=CreateRouteTable&VpcId=vpc-1a2b3c4d&DryRun=true");
}
public void deleteRouteTable() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/delete_route_table.xml");
final boolean deleted = routeTableApi().deleteRouteTable(DEFAULT_REGION, "rtb-8bda6cef");
assertTrue(deleted, "Failed to match 'true' data in test response");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DeleteRouteTable&RouteTableId=rtb-8bda6cef");
}
public void deleteRouteTableWithOptions() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(PRECONDITION_FAILED, DEFAULT_REGION, "/dry_run.xml");
try {
routeTableApi().deleteRouteTable(DEFAULT_REGION, "rtb-8bda6cef", dryRun());
Assert.fail("Expected 'DryRunOperation' exception was not thrown");
} catch (AWSResponseException e) {
assertDryRun(e);
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DeleteRouteTable&RouteTableId=rtb-8bda6cef&DryRun=true");
}
public void deleteRouteTableNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final boolean deleted = routeTableApi().deleteRouteTable(DEFAULT_REGION, "rtb-8bda6cef");
assertFalse(deleted, "Non-existent table reported as successfully deleted");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DeleteRouteTable&RouteTableId=rtb-8bda6cef");
}
public void associateRouteTable() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/associate_route_table.xml");
final String associationId = routeTableApi().associateRouteTable(DEFAULT_REGION, "rtb-8c95c0eb", "subnet-6986410e");
assertEquals(associationId, "rtbassoc-fb7fed9d", "Failed to associate route");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=AssociateRouteTable&RouteTableId=rtb-8c95c0eb&SubnetId=subnet-6986410e");
}
public void associateRouteTableNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final String associationId = routeTableApi().associateRouteTable(DEFAULT_REGION, "rtb-8c95c0eb", "subnet-6986410e");
assertNull(associationId, "Returned id for non-existent route table: " + associationId);
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=AssociateRouteTable&RouteTableId=rtb-8c95c0eb&SubnetId=subnet-6986410e");
}
public void associateRouteTableWithOptions() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(PRECONDITION_FAILED, DEFAULT_REGION, "/dry_run.xml");
try {
routeTableApi().associateRouteTable(DEFAULT_REGION, "rtb-8c95c0eb", "subnet-6986410e", dryRun());
} catch (AWSResponseException e) {
assertDryRun(e);
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION,
"Action=AssociateRouteTable&RouteTableId=rtb-8c95c0eb&SubnetId=subnet-6986410e&DryRun=true");
}
public void disassociateRouteTable() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/disassociate_route_table.xml");
final boolean result = routeTableApi().disassociateRouteTable(DEFAULT_REGION, "rtbassoc-fb7fed9d");
assertTrue(result, "Failed to disassociate route");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DisassociateRouteTable&AssociationId=rtbassoc-fb7fed9d");
}
public void disassociateRouteTableNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final boolean result = routeTableApi().disassociateRouteTable(DEFAULT_REGION, "rtbassoc-fb7fed9d");
assertFalse(result, "Non-existent table reported as successfully disassociated");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DisassociateRouteTable&AssociationId=rtbassoc-fb7fed9d");
}
public void disassociateRouteTablewithOptions() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(PRECONDITION_FAILED, DEFAULT_REGION, "/dry_run.xml");
try {
routeTableApi().disassociateRouteTable(DEFAULT_REGION, "rtbassoc-fb7fed9d", dryRun());
} catch (AWSResponseException e) {
assertDryRun(e);
}
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DisassociateRouteTable&AssociationId=rtbassoc-fb7fed9d&DryRun=true");
}
public void createRoute() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/create_route.xml");
final boolean created = routeTableApi().createRoute(DEFAULT_REGION, "rtb-a77f2ac0",
gatewayId("igw-97e68af3").destinationCidrBlock("172.18.19.0/24"));
assertTrue(created, "Failed to match 'true' in test data response");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION,
"Action=CreateRoute&RouteTableId=rtb-a77f2ac0&GatewayId=igw-97e68af3&DestinationCidrBlock=172.18.19.0/24");
}
public void createRouteNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/create_route.xml");
final boolean created = routeTableApi().createRoute(DEFAULT_REGION, "rtb-a77f2ac0",
gatewayId("igw-97e68af3").destinationCidrBlock("172.18.19.0/24"));
assertTrue(created, "Failed to match 'true' in test data response");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION,
"Action=CreateRoute&RouteTableId=rtb-a77f2ac0&GatewayId=igw-97e68af3&DestinationCidrBlock=172.18.19.0/24");
}
public void replaceRoute() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final boolean created = routeTableApi().replaceRoute(DEFAULT_REGION, "rtb-a77f2ac0",
gatewayId("vgw-1d00376e").destinationCidrBlock("172.18.19.0/24"));
assertFalse(created, "Reported successful replace of route in non-existent route table");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION,
"Action=ReplaceRoute&RouteTableId=rtb-a77f2ac0&GatewayId=vgw-1d00376e&DestinationCidrBlock=172.18.19.0/24");
}
public void replaceRouteNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/replace_route.xml");
final boolean created = routeTableApi().replaceRoute(DEFAULT_REGION, "rtb-a77f2ac0",
gatewayId("vgw-1d00376e").destinationCidrBlock("172.18.19.0/24"));
assertTrue(created, "Failed to match 'true' in test data response");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION,
"Action=ReplaceRoute&RouteTableId=rtb-a77f2ac0&GatewayId=vgw-1d00376e&DestinationCidrBlock=172.18.19.0/24");
}
public void deleteRoute() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueueXml(DEFAULT_REGION, "/delete_route.xml");
final boolean deleted = routeTableApi().deleteRoute(DEFAULT_REGION, "rtb-a77f2ac0",
destinationCidrBlock("172.18.19.0/24"));
assertTrue(deleted, "Failed to match 'true' in test data response");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DeleteRoute&RouteTableId=rtb-a77f2ac0&DestinationCidrBlock=172.18.19.0/24");
}
public void deleteRouteNotFound() throws Exception {
enqueueRegions(DEFAULT_REGION);
enqueue(DEFAULT_REGION, new MockResponse().setResponseCode(404));
final boolean deleted = routeTableApi().deleteRoute(DEFAULT_REGION, "rtb-a77f2ac0",
destinationCidrBlock("172.18.19.0/24"));
assertFalse(deleted, "Reported successful delete of route in non-existent route table");
assertPosted(DEFAULT_REGION, "Action=DescribeRegions");
assertPosted(DEFAULT_REGION, "Action=DeleteRoute&RouteTableId=rtb-a77f2ac0&DestinationCidrBlock=172.18.19.0/24");
}
private void assertDryRun(AWSResponseException e) {
assertEquals(e.getError().getCode(), "DryRunOperation", "Expected DryRunOperation but got " + e.getError());
}
private RouteTableApi routeTableApi() {
return api().getRouteTableApi().get();
}
}

View File

@ -26,10 +26,13 @@ import static org.jclouds.util.Strings2.toStringAndClose;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.ws.rs.core.Response;
import org.jclouds.Constants;
import org.jclouds.ContextBuilder;
import org.jclouds.aws.ec2.AWSEC2Api;
@ -155,6 +158,13 @@ public class BaseAWSEC2ApiMockTest {
new MockResponse().addHeader(CONTENT_TYPE, APPLICATION_XML).setBody(describeRegionsResponse.toString()));
}
protected void enqueueXml(Response.Status status, String region, String resource) {
enqueue(region, new MockResponse()
.setStatus("HTTP/1.1 " + status.getStatusCode() + " " + status.getReasonPhrase())
.addHeader(CONTENT_TYPE, APPLICATION_XML)
.setBody(stringFromResource(resource)));
}
protected void enqueueXml(String region, String resource) {
enqueue(region,
new MockResponse().addHeader(CONTENT_TYPE, APPLICATION_XML).setBody(stringFromResource(resource)));
@ -162,7 +172,12 @@ public class BaseAWSEC2ApiMockTest {
protected String stringFromResource(String resourceName) {
try {
return toStringAndClose(getClass().getResourceAsStream(resourceName));
final InputStream resourceAsStream = getClass().getResourceAsStream(resourceName);
if (resourceAsStream == null) {
throw new IllegalArgumentException(
"Could not find resource '" + resourceName + "' in class " + getClass().getSimpleName());
}
return toStringAndClose(resourceAsStream);
} catch (IOException e) {
throw propagate(e);
}

View File

@ -0,0 +1,4 @@
<AssociateRouteTableResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>f87d1645-3919-4e26-b98f-852c47def4ee</requestId>
<associationId>rtbassoc-fb7fed9d</associationId>
</AssociateRouteTableResponse>

View File

@ -0,0 +1,4 @@
<CreateRouteResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>3b1d5abc-0d50-4367-87c1-a4dcc2f8b928</requestId>
<return>true</return>
</CreateRouteResponse>

View File

@ -0,0 +1,24 @@
<CreateRouteTableResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<routeTable>
<routeTableId>rtb-8bda6cef</routeTableId>
<vpcId>vpc-1a2b3c4d</vpcId>
<routeSet>
<item>
<destinationCidrBlock>10.0.0.0/16</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
<origin>CreateRouteTable</origin>
</item>
<item>
<destinationIpv6CidrBlock>2001:db8:1234:1a00::/56</destinationIpv6CidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
<origin>CreateRouteTable</origin>
</item>
</routeSet>
<associationSet/>
<propagatingVgwSet/>
<tagSet/>
</routeTable>
</CreateRouteTableResponse>

View File

@ -0,0 +1,4 @@
<DeleteRouteResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>6d6d0513-5af2-46ae-8f8a-24c8c3ab0f70</requestId>
<return>true</return>
</DeleteRouteResponse>

View File

@ -0,0 +1,4 @@
<DeleteRouteTableResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<return>true</return>
</DeleteRouteTableResponse>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<DescribeRouteTablesResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>0fe3e6ca-5b09-4722-9d81-1f341376c830</requestId>
<routeTableSet>
<item>
<routeTableId>rtb-80a3fae4</routeTableId>
<vpcId>vpc-6dcb5609</vpcId>
<routeSet>
<item>
<destinationCidrBlock>172.31.0.0/16</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
</item>
<item>
<destinationCidrBlock>0.0.0.0/0</destinationCidrBlock>
<gatewayId>igw-dcdcc7b9</gatewayId>
<state>active</state>
</item>
</routeSet>
<associationSet>
<item>
<routeTableAssociationId>rtbassoc-f173c296</routeTableAssociationId>
<routeTableId>rtb-80a3fae4</routeTableId>
<main>true</main>
</item>
</associationSet>
<tagSet/>
</item>
<item>
<routeTableId>rtb-d4605bb0</routeTableId>
<vpcId>vpc-924731f6</vpcId>
<routeSet>
<item>
<destinationCidrBlock>10.0.0.0/16</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
</item>
<item>
<destinationCidrBlock>0.0.0.0/0</destinationCidrBlock>
<gatewayId>igw-5af2023e</gatewayId>
<state>active</state>
</item>
</routeSet>
<associationSet>
<item>
<routeTableAssociationId>rtbassoc-a08aefc7</routeTableAssociationId>
<routeTableId>rtb-d4605bb0</routeTableId>
<main>true</main>
</item>
</associationSet>
<tagSet/>
</item>
<item>
<routeTableId>rtb-e6c98381</routeTableId>
<vpcId>vpc-6fa76308</vpcId>
<routeSet>
<item>
<destinationCidrBlock>10.20.30.0/24</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>active</state>
</item>
</routeSet>
<associationSet>
<item>
<routeTableAssociationId>rtbassoc-2d2dbe4b</routeTableAssociationId>
<routeTableId>rtb-e6c98381</routeTableId>
<main>true</main>
</item>
</associationSet>
<tagSet/>
</item>
</routeTableSet>
</DescribeRouteTablesResponse>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<DescribeRouteTablesResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>0fe3e6ca-5b09-4722-9d81-1f341376c830</requestId>
<routeTableSet>
<item>
<routeTableId>rtb-80a3fae4</routeTableId>
<vpcId>vpc-6dcb5609</vpcId>
<routeSet>
<item>
<destinationCidrBlock>172.31.0.0/16</destinationCidrBlock>
<gatewayId>local</gatewayId>
<state>bogus</state>
</item>
</routeSet>
<associationSet/>
<tagSet/>
</item>
</routeTableSet>
</DescribeRouteTablesResponse>

View File

@ -0,0 +1,4 @@
<DisassociateRouteTableResponse xmlns="http://ec2.amazonaws.com/doc/2012-06-01/">
<requestId>36e6a0e6-cd7a-45fc-8539-ba05cc070a3f</requestId>
<return>true</return>
</DisassociateRouteTableResponse>

View File

@ -0,0 +1,4 @@
<ReplaceRouteResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
<return>true</return>
</ReplaceRouteResponse>