You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2017/05/29 08:31:29 UTC
[2/4] jclouds git commit: Add RouteTable API.
Add RouteTable API.
Limitations:
Does not contain support for VgwRoutePropagation.
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/b3d21f96
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/b3d21f96
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/b3d21f96
Branch: refs/heads/master
Commit: b3d21f965288b44cadc750ff1dde2ec7ac45fff6
Parents: a900628
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Fri May 12 16:44:30 2017 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Mon May 29 10:22:46 2017 +0200
----------------------------------------------------------------------
.../java/org/jclouds/aws/ec2/AWSEC2Api.java | 17 +-
.../BindRouteTableIdsToIndexedFormParams.java | 32 ++
.../java/org/jclouds/aws/ec2/domain/Route.java | 107 +++++++
.../org/jclouds/aws/ec2/domain/RouteTable.java | 99 ++++++
.../aws/ec2/domain/RouteTableAssociation.java | 71 +++++
.../jclouds/aws/ec2/features/RouteTableApi.java | 279 +++++++++++++++++
.../aws/ec2/options/InternetGatewayOptions.java | 5 +-
.../jclouds/aws/ec2/options/RouteOptions.java | 254 ++++++++++++++++
.../aws/ec2/options/RouteTableOptions.java | 75 +++++
.../xml/AssociateRouteTableResponseHandler.java | 40 +++
.../xml/CreateRouteTableResponseHandler.java | 55 ++++
.../xml/DescribeRouteTablesResponseHandler.java | 100 ++++++
.../org/jclouds/aws/ec2/xml/RouteHandler.java | 48 +++
.../jclouds/aws/ec2/xml/RouteSetHandler.java | 77 +++++
.../xml/RouteTableAssociationSetHandler.java | 79 +++++
.../jclouds/aws/ec2/xml/RouteTableHandler.java | 116 +++++++
.../features/InternetGatewayApiLiveTest.java | 8 +-
.../features/InternetGatewayApiMockTest.java | 8 +-
.../aws/ec2/features/RouteTableApiLiveTest.java | 293 ++++++++++++++++++
.../aws/ec2/features/RouteTableApiMockTest.java | 301 +++++++++++++++++++
.../aws/ec2/internal/BaseAWSEC2ApiMockTest.java | 17 +-
.../test/resources/associate_route_table.xml | 4 +
.../create_internet_gateway_dry_run.xml | 11 -
.../aws-ec2/src/test/resources/create_route.xml | 4 +
.../src/test/resources/create_route_table.xml | 24 ++
.../aws-ec2/src/test/resources/delete_route.xml | 4 +
.../src/test/resources/delete_route_table.xml | 4 +
.../test/resources/describe_route_tables.xml | 74 +++++
.../resources/describe_route_tables_invalid.xml | 20 ++
.../test/resources/disassociate_route_table.xml | 4 +
.../aws-ec2/src/test/resources/dry_run.xml | 11 +
.../src/test/resources/replace_route.xml | 4 +
32 files changed, 2225 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java
index a094ce6..d2808af 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Api.java
@@ -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
+ );
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindRouteTableIdsToIndexedFormParams.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindRouteTableIdsToIndexedFormParams.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindRouteTableIdsToIndexedFormParams.java
new file mode 100644
index 0000000..4c2ec42
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/binders/BindRouteTableIdsToIndexedFormParams.java
@@ -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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/Route.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/Route.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/Route.java
new file mode 100644
index 0000000..39d2d92
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/Route.java
@@ -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();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTable.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTable.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTable.java
new file mode 100644
index 0000000..b4eb182
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTable.java
@@ -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();
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTableAssociation.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTableAssociation.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTableAssociation.java
new file mode 100644
index 0000000..2b25afa
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/RouteTableAssociation.java
@@ -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();
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java
new file mode 100644
index 0000000..3190e60
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/features/RouteTableApi.java
@@ -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);
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/InternetGatewayOptions.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/InternetGatewayOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/InternetGatewayOptions.java
index 6449ae4..cff7311 100644
--- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/InternetGatewayOptions.java
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/InternetGatewayOptions.java
@@ -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");
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteOptions.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteOptions.java
new file mode 100644
index 0000000..751bb29
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteOptions.java
@@ -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);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteTableOptions.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteTableOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteTableOptions.java
new file mode 100644
index 0000000..4960d4e
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/RouteTableOptions.java
@@ -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();
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AssociateRouteTableResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AssociateRouteTableResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AssociateRouteTableResponseHandler.java
new file mode 100644
index 0000000..fa104fb
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AssociateRouteTableResponseHandler.java
@@ -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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/CreateRouteTableResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/CreateRouteTableResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/CreateRouteTableResponseHandler.java
new file mode 100644
index 0000000..eacb4f2
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/CreateRouteTableResponseHandler.java
@@ -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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeRouteTablesResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeRouteTablesResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeRouteTablesResponseHandler.java
new file mode 100644
index 0000000..0146f67
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeRouteTablesResponseHandler.java
@@ -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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteHandler.java
new file mode 100644
index 0000000..2956cff
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteHandler.java
@@ -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();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteSetHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteSetHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteSetHandler.java
new file mode 100644
index 0000000..d5326c4
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteSetHandler.java
@@ -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);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableAssociationSetHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableAssociationSetHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableAssociationSetHandler.java
new file mode 100644
index 0000000..4a355d7
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableAssociationSetHandler.java
@@ -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);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableHandler.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableHandler.java
new file mode 100644
index 0000000..733815d
--- /dev/null
+++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/RouteTableHandler.java
@@ -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);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiLiveTest.java
index c44acf4..e2b2d5f 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiLiveTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiLiveTest.java
@@ -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());
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiMockTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiMockTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiMockTest.java
index 8c65702..ef39e93 100644
--- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiMockTest.java
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/InternetGatewayApiMockTest.java
@@ -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();
}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/b3d21f96/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java
new file mode 100644
index 0000000..3c57984
--- /dev/null
+++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/features/RouteTableApiLiveTest.java
@@ -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());
+ }
+
+}