Repository: jclouds-labs-aws
Updated Branches:
  refs/heads/master 3eb2646b4 -> e248c37dc


- added subnet api
    - added new binders
    - added new methods to the load balancer api
    - renamed availabilityZoneResultHandler to more generic MemberResultHandler
    - updated jclouds version to 2.1.0
    - added BaseELBApiMockTest
    - added subnet mock test
    - added com.squareup.okhttp dependency for mock tests
    - removed checkNotNull on policyType description because this field is not 
always present
    - made some of the tests signle threaded
    - updated BindSubnetIdsToIndexedFormParams for readability
    - added subnet live test


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/commit/e248c37d
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/tree/e248c37d
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/diff/e248c37d

Branch: refs/heads/master
Commit: e248c37dce384c285fc80425b24256f502d8c8ac
Parents: 3eb2646
Author: Justin Thompson <[email protected]>
Authored: Fri Jan 27 17:00:07 2017 +0000
Committer: Andrea Turli <[email protected]>
Committed: Fri Jan 27 18:53:57 2017 +0100

----------------------------------------------------------------------
 elb/pom.xml                                     |  12 ++
 elb/src/main/java/org/jclouds/elb/ELBApi.java   |  18 +++
 .../binders/BindHealthCheckToFormParams.java    |  47 ++++++
 .../BindListenerPortsToIndexedFormParams.java   |  39 +++++
 .../BindSubnetIdsToIndexedFormParams.java       |  48 ++++++
 .../org/jclouds/elb/domain/HealthCheck.java     |   2 +-
 .../java/org/jclouds/elb/domain/PolicyType.java |   2 +-
 .../elb/features/AvailabilityZoneApi.java       |  10 +-
 .../jclouds/elb/features/HealthCheckApi.java    |  65 ++++++++
 .../jclouds/elb/features/LoadBalancerApi.java   | 128 +++++++++++----
 .../org/jclouds/elb/features/SubnetApi.java     |  91 +++++++++++
 .../elb/xml/AvailabilityZonesResultHandler.java |  44 ------
 .../jclouds/elb/xml/MemberResultHandler.java    |  44 ++++++
 .../java/org/jclouds/elb/xml/PolicyHandler.java |   3 +-
 .../elb/features/HealthCheckApiLiveTest.java    |  80 ++++++++++
 .../elb/features/HealthCheckApiMockTest.java    |  75 +++++++++
 .../jclouds/elb/features/PolicyApiLiveTest.java |   3 +-
 .../jclouds/elb/features/SubnetApiLiveTest.java | 156 +++++++++++++++++++
 .../jclouds/elb/features/SubnetApiMockTest.java |  75 +++++++++
 .../elb/internal/BaseELBApiMockTest.java        | 103 ++++++++++++
 .../parse/AttachSubnetsResultHandlerTest.java   |  49 ++++++
 .../AvailabilityZonesResultHandlerTest.java     |   4 +-
 .../parse/DetachSubnetsResultHandlerTest.java   |  49 ++++++
 .../elb/parse/HealthCheckResultHandlerTest.java |  53 +++++++
 .../attach_load_balancer_to_subnets.xml         |  10 ++
 .../test/resources/configure_health_check.xml   |  14 ++
 .../detach_load_balancer_from_subnets.xml       |  10 ++
 .../rds/features/InstanceApiLiveTest.java       |   2 +-
 .../rds/features/SecurityGroupApiLiveTest.java  |   2 +-
 29 files changed, 1152 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/pom.xml
----------------------------------------------------------------------
diff --git a/elb/pom.xml b/elb/pom.xml
index 4d60dac..45079d0 100644
--- a/elb/pom.xml
+++ b/elb/pom.xml
@@ -117,6 +117,18 @@
       <artifactId>auto-service</artifactId>
       <optional>true</optional>
     </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp</groupId>
+      <artifactId>mockwebserver</artifactId>
+      <scope>test</scope>
+      <exclusions>
+        <!-- Already provided by jclouds-sshj -->
+        <exclusion>
+          <groupId>org.bouncycastle</groupId>
+          <artifactId>bcprov-jdk15on</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
   </dependencies>
 
   <profiles>

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/ELBApi.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/ELBApi.java 
b/elb/src/main/java/org/jclouds/elb/ELBApi.java
index f1a7910..caa70ad 100644
--- a/elb/src/main/java/org/jclouds/elb/ELBApi.java
+++ b/elb/src/main/java/org/jclouds/elb/ELBApi.java
@@ -21,9 +21,11 @@ import java.util.Set;
 
 import org.jclouds.aws.filters.FormSigner;
 import org.jclouds.elb.features.AvailabilityZoneApi;
+import org.jclouds.elb.features.HealthCheckApi;
 import org.jclouds.elb.features.InstanceApi;
 import org.jclouds.elb.features.LoadBalancerApi;
 import org.jclouds.elb.features.PolicyApi;
+import org.jclouds.elb.features.SubnetApi;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.location.Region;
 import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
@@ -91,4 +93,20 @@ public interface ELBApi extends Closeable {
    AvailabilityZoneApi getAvailabilityZoneApiForRegion(
             @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) 
@Nullable String region);
 
+   /**
+    * Provides access to HealthCheck features.
+    */
+   @Delegate
+   HealthCheckApi getHealthCheckApi();
+
+   @Delegate
+   HealthCheckApi getHealthCheckApiForRegion(
+           @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) 
@Nullable String region);
+
+   /**
+    * Provides access to Subnet features.
+    */
+   @Delegate
+   SubnetApi getSubnetApi();
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/binders/BindHealthCheckToFormParams.java
----------------------------------------------------------------------
diff --git 
a/elb/src/main/java/org/jclouds/elb/binders/BindHealthCheckToFormParams.java 
b/elb/src/main/java/org/jclouds/elb/binders/BindHealthCheckToFormParams.java
new file mode 100644
index 0000000..5822e24
--- /dev/null
+++ b/elb/src/main/java/org/jclouds/elb/binders/BindHealthCheckToFormParams.java
@@ -0,0 +1,47 @@
+/*
+ * 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.elb.binders;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.elb.domain.HealthCheck;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+
+import com.google.common.collect.ImmutableMultimap;
+
+public class BindHealthCheckToFormParams implements Binder {
+
+    /**
+     * {@inheritDoc}
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+        HealthCheck healthCheck = checkNotNull(input, "healthCheck must be 
set!") instanceof HealthCheck ? 
+                HealthCheck.class.cast(input) : (HealthCheck) input;
+
+        ImmutableMultimap.Builder<String, String> formParameters = 
ImmutableMultimap.builder();
+        formParameters.put("HealthCheck.HealthyThreshold", 
healthCheck.getHealthyThreshold() + "");
+        formParameters.put("HealthCheck.UnhealthyThreshold", 
healthCheck.getUnhealthyThreshold() + "");
+        formParameters.put("HealthCheck.Target", healthCheck.getTarget());
+        formParameters.put("HealthCheck.Interval", healthCheck.getInterval() + 
"");
+        formParameters.put("HealthCheck.Timeout", healthCheck.getTimeout() + 
"");
+        return (R) 
request.toBuilder().replaceFormParams(formParameters.build()).build();
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/binders/BindListenerPortsToIndexedFormParams.java
----------------------------------------------------------------------
diff --git 
a/elb/src/main/java/org/jclouds/elb/binders/BindListenerPortsToIndexedFormParams.java
 
b/elb/src/main/java/org/jclouds/elb/binders/BindListenerPortsToIndexedFormParams.java
new file mode 100644
index 0000000..f62b4b0
--- /dev/null
+++ 
b/elb/src/main/java/org/jclouds/elb/binders/BindListenerPortsToIndexedFormParams.java
@@ -0,0 +1,39 @@
+/*
+ * 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.elb.binders;
+
+import static 
org.jclouds.aws.util.AWSUtils.indexIterableToFormValuesWithPrefix;
+
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+
+/**
+ * Binds the Iterable<String> to form parameters named with prefix 
LoadBalancerPorts.member
+ */
+@Singleton
+public class BindListenerPortsToIndexedFormParams implements Binder {
+   
+   @SuppressWarnings("unchecked")
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      return indexIterableToFormValuesWithPrefix(request, 
"LoadBalancerPorts.member", input);
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/binders/BindSubnetIdsToIndexedFormParams.java
----------------------------------------------------------------------
diff --git 
a/elb/src/main/java/org/jclouds/elb/binders/BindSubnetIdsToIndexedFormParams.java
 
b/elb/src/main/java/org/jclouds/elb/binders/BindSubnetIdsToIndexedFormParams.java
new file mode 100644
index 0000000..a8ce0fd
--- /dev/null
+++ 
b/elb/src/main/java/org/jclouds/elb/binders/BindSubnetIdsToIndexedFormParams.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.elb.binders;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableMultimap.Builder;
+
+/**
+ * Binds the Iterable<String> to form parameters named with 
Subnets.member.index
+ */
+@Singleton
+public class BindSubnetIdsToIndexedFormParams implements Binder {
+   
+   @SuppressWarnings("unchecked")
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      Iterable<?> values = Iterable.class.cast(checkNotNull(input, 
"subnetIds"));
+      Builder<String, String> builder = ImmutableMultimap.builder();
+      int i = 1;
+      for (Object o : values) {
+         builder.put("Subnets.member." + (i++), o.toString());
+      }
+      ImmutableMultimap<String, String> forms = builder.build();
+      return (R) (forms.size() == 0 ? request : 
request.toBuilder().replaceFormParams(forms).build());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/domain/HealthCheck.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/domain/HealthCheck.java 
b/elb/src/main/java/org/jclouds/elb/domain/HealthCheck.java
index 43fc3a5..eb109b1 100644
--- a/elb/src/main/java/org/jclouds/elb/domain/HealthCheck.java
+++ b/elb/src/main/java/org/jclouds/elb/domain/HealthCheck.java
@@ -29,7 +29,7 @@ import com.google.common.base.Objects.ToStringHelper;
  * 
  * 
  * @see <a
- *      
href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/ConfigureHealthCheck.html";
+ *      
href="http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ConfigureHealthCheck.html";
  *      >doc</a>
  */
 public class HealthCheck {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/domain/PolicyType.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/domain/PolicyType.java 
b/elb/src/main/java/org/jclouds/elb/domain/PolicyType.java
index a4057ed..73c0668 100644
--- a/elb/src/main/java/org/jclouds/elb/domain/PolicyType.java
+++ b/elb/src/main/java/org/jclouds/elb/domain/PolicyType.java
@@ -95,7 +95,7 @@ public class PolicyType {
 
    protected PolicyType(String name, String description, 
Iterable<AttributeMetadata<?>> attributeMetadata) {
       this.name = checkNotNull(name, "name");
-      this.description = checkNotNull(description, "description");
+      this.description = description;
       this.attributeMetadata = 
ImmutableSet.copyOf(checkNotNull(attributeMetadata, "attributeMetadata"));
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/features/AvailabilityZoneApi.java
----------------------------------------------------------------------
diff --git 
a/elb/src/main/java/org/jclouds/elb/features/AvailabilityZoneApi.java 
b/elb/src/main/java/org/jclouds/elb/features/AvailabilityZoneApi.java
index 3dc4624..67756a1 100644
--- a/elb/src/main/java/org/jclouds/elb/features/AvailabilityZoneApi.java
+++ b/elb/src/main/java/org/jclouds/elb/features/AvailabilityZoneApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.Path;
 
 import org.jclouds.aws.filters.FormSigner;
 import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
-import org.jclouds.elb.xml.AvailabilityZonesResultHandler;
+import org.jclouds.elb.xml.MemberResultHandler;
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.FormParams;
 import org.jclouds.rest.annotations.RequestFilters;
@@ -70,7 +70,7 @@ public interface AvailabilityZoneApi {
    @Named("EnableAvailabilityZonesForLoadBalancer")
    @POST
    @Path("/")
-   @XMLResponseParser(AvailabilityZonesResultHandler.class)
+   @XMLResponseParser(MemberResultHandler.class)
    @FormParams(keys = ACTION, values = 
"EnableAvailabilityZonesForLoadBalancer")
    Set<String> addAvailabilityZonesToLoadBalancer(
             @BinderParam(BindAvailabilityZonesToIndexedFormParams.class) 
Iterable<String> zones,
@@ -83,7 +83,7 @@ public interface AvailabilityZoneApi {
    @Named("EnableAvailabilityZonesForLoadBalancer")
    @POST
    @Path("/")
-   @XMLResponseParser(AvailabilityZonesResultHandler.class)
+   @XMLResponseParser(MemberResultHandler.class)
    @FormParams(keys = ACTION, values = 
"EnableAvailabilityZonesForLoadBalancer")
    Set<String> addAvailabilityZoneToLoadBalancer(
             @FormParam("AvailabilityZones.member.1") String zone,
@@ -128,7 +128,7 @@ public interface AvailabilityZoneApi {
    @Named("DisableAvailabilityZonesForLoadBalancer")
    @POST
    @Path("/")
-   @XMLResponseParser(AvailabilityZonesResultHandler.class)
+   @XMLResponseParser(MemberResultHandler.class)
    @FormParams(keys = ACTION, values = 
"DisableAvailabilityZonesForLoadBalancer")
    Set<String> removeAvailabilityZonesFromLoadBalancer(
             @BinderParam(BindAvailabilityZonesToIndexedFormParams.class) 
Iterable<String> zones,
@@ -140,7 +140,7 @@ public interface AvailabilityZoneApi {
    @Named("DisableAvailabilityZonesForLoadBalancer")
    @POST
    @Path("/")
-   @XMLResponseParser(AvailabilityZonesResultHandler.class)
+   @XMLResponseParser(MemberResultHandler.class)
    @FormParams(keys = ACTION, values = 
"DisableAvailabilityZonesForLoadBalancer")
    Set<String> removeAvailabilityZoneFromLoadBalancer(
             @FormParam("AvailabilityZones.member.1") String zone,

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/features/HealthCheckApi.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/features/HealthCheckApi.java 
b/elb/src/main/java/org/jclouds/elb/features/HealthCheckApi.java
new file mode 100644
index 0000000..44524d9
--- /dev/null
+++ b/elb/src/main/java/org/jclouds/elb/features/HealthCheckApi.java
@@ -0,0 +1,65 @@
+/*
+ * 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.elb.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.elb.binders.BindHealthCheckToFormParams;
+import org.jclouds.elb.domain.HealthCheck;
+import org.jclouds.elb.xml.HealthCheckHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to Amazon ELB Health Check functionality via the Query API
+ * <p/>
+ */
+@RequestFilters(FormSigner.class)
+@Consumes(MediaType.APPLICATION_XML)
+@VirtualHost
+public interface HealthCheckApi {
+
+   /**
+    * @see <a 
href="http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_ConfigureHealthCheck.html";>doc</a>
+    *      
+    * @param loadBalancerName
+    * @param healthCheck
+    * @return
+    */
+   @Named("ConfigureHealthCheck")
+   @POST
+   @Path("/")
+   @XMLResponseParser(HealthCheckHandler.class)
+   @FormParams(keys = ACTION, values = "ConfigureHealthCheck")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   HealthCheck configureHealthCheck(@FormParam("LoadBalancerName") String 
loadBalancerName,
+                                         
@BinderParam(BindHealthCheckToFormParams.class) HealthCheck healthCheck);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/features/LoadBalancerApi.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/features/LoadBalancerApi.java 
b/elb/src/main/java/org/jclouds/elb/features/LoadBalancerApi.java
index 6daa3b7..4a2cf10 100644
--- a/elb/src/main/java/org/jclouds/elb/features/LoadBalancerApi.java
+++ b/elb/src/main/java/org/jclouds/elb/features/LoadBalancerApi.java
@@ -31,6 +31,7 @@ import org.jclouds.aws.filters.FormSigner;
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
+import org.jclouds.elb.binders.BindListenerPortsToIndexedFormParams;
 import org.jclouds.elb.binders.BindListenersToFormParams;
 import org.jclouds.elb.binders.BindSecurityGroupsToIndexedFormParams;
 import org.jclouds.elb.binders.BindSubnetsToIndexedFormParams;
@@ -53,7 +54,7 @@ import org.jclouds.rest.annotations.XMLResponseParser;
 /**
  * Provides access to Amazon ELB via the Query API
  * <p/>
- * 
+ *
  * @see <a 
href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference";
  *      >doc</a>
  */
@@ -61,14 +62,38 @@ import org.jclouds.rest.annotations.XMLResponseParser;
 @VirtualHost
 public interface LoadBalancerApi {
 
+    /**
+     * Creates listeners for an existing load balancer.
+     *
+     * @param name Name of the loadBalancer to create the listeners in.
+     * @param listeners The listeners to create.
+     * @return null if load balancer is not found
+     */
+    @Named("CreateLoadBalancerListeners")
+    @POST
+    @Path("/")
+    @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
+    @FormParams(keys = ACTION, values = "CreateLoadBalancerListeners")
+    String createLoadBalancerListeners(@FormParam("LoadBalancerName") String 
name,
+                                       
@BinderParam(BindListenersToFormParams.class) Iterable<Listener> listeners);
+
+   @Named("CreateLoadBalancer")
+   @POST
+   @Path("/")
+   @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
+   @FormParams(keys = ACTION, values = "CreateLoadBalancer")
+   String createLoadBalancerInAvailabilityZones(@FormParam("LoadBalancerName") 
String name,
+                                             
@BinderParam(BindListenersToFormParams.class) Iterable<Listener> listeners,
+                                             
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) Iterable<String> 
availabilityZones);
+
    @Named("CreateLoadBalancer")
    @POST
    @Path("/")
    @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
    @FormParams(keys = ACTION, values = "CreateLoadBalancer")
    String createListeningInAvailabilityZones(@FormParam("LoadBalancerName") 
String name,
-             @BinderParam(BindListenersToFormParams.class) Listener listeners,
-             @BinderParam(BindAvailabilityZonesToIndexedFormParams.class) 
Iterable<String> availabilityZones);
+                                             
@BinderParam(BindListenersToFormParams.class) Listener listeners,
+                                             
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) Iterable<String> 
availabilityZones);
 
    @Named("CreateLoadBalancer")
    @POST
@@ -76,8 +101,17 @@ public interface LoadBalancerApi {
    @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
    @FormParams(keys = ACTION, values = "CreateLoadBalancer")
    String createListeningInAvailabilityZones(@FormParam("LoadBalancerName") 
String name,
-            @BinderParam(BindListenersToFormParams.class) Iterable<Listener> 
listeners,
-            @BinderParam(BindAvailabilityZonesToIndexedFormParams.class) 
Iterable<String> availabilityZones);
+                                             
@BinderParam(BindListenersToFormParams.class) Iterable<Listener> listeners,
+                                             
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) Iterable<String> 
availabilityZones);
+
+   @Named("CreateLoadBalancer")
+   @POST
+   @Path("/")
+   @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
+   @FormParams(keys = ACTION, values = "CreateLoadBalancer")
+   String createLoadBalancerInSubnets(@FormParam("LoadBalancerName") String 
name,
+                                             
@BinderParam(BindListenersToFormParams.class) Iterable<Listener> listeners,
+                                             
@BinderParam(BindSubnetsToIndexedFormParams.class) Iterable<String> subnets);
 
    @Named("CreateLoadBalancer")
    @POST
@@ -85,9 +119,9 @@ public interface LoadBalancerApi {
    @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
    @FormParams(keys = ACTION, values = "CreateLoadBalancer")
    String createListeningInSubnetAssignedToSecurityGroups(
-            @FormParam("LoadBalancerName") String name,
-            @FormParam("Subnets.member.1") String subnetId,
-            @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
+           @FormParam("LoadBalancerName") String name,
+           @FormParam("Subnets.member.1") String subnetId,
+           @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
 
    @Named("CreateLoadBalancer")
    @POST
@@ -95,15 +129,36 @@ public interface LoadBalancerApi {
    @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
    @FormParams(keys = ACTION, values = "CreateLoadBalancer")
    String createListeningInSubnetsAssignedToSecurityGroups(
-            @FormParam("LoadBalancerName") String name,
-            @BinderParam(BindSubnetsToIndexedFormParams.class) 
Iterable<String> subnetIds,
-            @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
+           @FormParam("LoadBalancerName") String name,
+           @BinderParam(BindSubnetsToIndexedFormParams.class) Iterable<String> 
subnetIds,
+           @BinderParam(BindListenersToFormParams.class) Iterable<Listener> 
listeners,
+           @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
+
+   @Named("CreateLoadBalancer")
+   @POST
+   @Path("/")
+   @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
+   @FormParams(keys = ACTION, values = "CreateLoadBalancer")
+   String createListeningInSubnetsAssignedToSecurityGroups(
+           @FormParam("LoadBalancerName") String name,
+           @BinderParam(BindSubnetsToIndexedFormParams.class) Iterable<String> 
subnetIds,
+           @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
+
+   @Named("CreateLoadBalancer")
+   @POST
+   @Path("/")
+   @XMLResponseParser(CreateLoadBalancerResponseHandler.class)
+   @FormParams(keys = ACTION, values = "CreateLoadBalancer")
+   String createListeningInSubnets(
+           @FormParam("LoadBalancerName") String name,
+           @BinderParam(BindListenersToFormParams.class) Iterable<Listener> 
listeners,
+           @BinderParam(BindSubnetsToIndexedFormParams.class) Iterable<String> 
subnetIds);
+
 
    /**
     * Retrieves information about the specified loadBalancer.
-    * 
-    * @param name
-    *           Name of the loadBalancer to get information about.
+    *
+    * @param name Name of the loadBalancer to get information about.
     * @return null if not found
     */
    @Named("DescribeLoadBalancers")
@@ -117,7 +172,7 @@ public interface LoadBalancerApi {
 
    /**
     * Lists the loadBalancers all load balancers
-    * 
+    *
     * @return the response object
     */
    @Named("DescribeLoadBalancers")
@@ -132,13 +187,11 @@ public interface LoadBalancerApi {
    /**
     * Returns detailed configuration information for the specified 
LoadBalancers. If there are none,
     * the action returns an empty list.
-    * 
+    *
     * <br/>
     * You can paginate the results using the {@link ListLoadBalancersOptions 
parameter}
-    * 
-    * @param options
-    *           the options describing the loadBalancers query
-    * 
+    *
+    * @param options the options describing the loadBalancers query
     * @return the response object
     */
    @Named("DescribeLoadBalancers")
@@ -151,26 +204,24 @@ public interface LoadBalancerApi {
 
    /**
     * Deletes the specified LoadBalancer.
-    * 
+    *
     * <p/>
     * If attempting to recreate the LoadBalancer, the api must reconfigure all 
the settings. The
     * DNS name associated with a deleted LoadBalancer will no longer be 
usable. Once deleted, the
     * name and associated DNS record of the LoadBalancer no longer exist and 
traffic sent to any of
     * its IP addresses will no longer be delivered to api instances. The api 
will not receive
     * the same DNS name even if a new LoadBalancer with same LoadBalancerName 
is created.
-    * 
+    *
     * <p/>
     * To successfully call this API, the api must provide the same account 
credentials as were
     * used to create the LoadBalancer.
-    * 
+    *
     * <h4>Note</h4>
-    * 
+    *
     * By design, if the LoadBalancer does not exist or has already been 
deleted, DeleteLoadBalancer
     * still succeeds.
-    * 
-    * 
-    * @param name
-    *           Name of the load balancer
+    *
+    * @param name Name of the load balancer
     */
    @Named("DeleteLoadBalancer")
    @POST
@@ -178,4 +229,25 @@ public interface LoadBalancerApi {
    @Fallback(VoidOnNotFoundOr404.class)
    @FormParams(keys = ACTION, values = "DeleteLoadBalancer")
    void delete(@FormParam("LoadBalancerName") String name);
+
+
+   @Named("DeleteLoadBalancerListeners")
+   @POST
+   @Path("/")
+   @Fallback(VoidOnNotFoundOr404.class)
+   @FormParams(keys = ACTION, values = "DeleteLoadBalancerListeners")
+   void deleteLoadBalancerListeners(
+           @FormParam("LoadBalancerName") String loadBalancerName,
+           @BinderParam(BindListenerPortsToIndexedFormParams.class) 
Iterable<Integer> listenerPorts);
+
+
+   @Named("ApplySecurityGroupsToLoadBalancer")
+   @POST
+   @Path("/")
+   @Fallback(VoidOnNotFoundOr404.class)
+   @FormParams(keys = ACTION, values = "ApplySecurityGroupsToLoadBalancer")
+   void applySecurityGroupsToLoadBalancer(
+           @FormParam("LoadBalancerName") String loadBalancerName,
+           @BinderParam(BindSecurityGroupsToIndexedFormParams.class) 
Iterable<String> securityGroupIds);
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/features/SubnetApi.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/features/SubnetApi.java 
b/elb/src/main/java/org/jclouds/elb/features/SubnetApi.java
new file mode 100644
index 0000000..b700ffe
--- /dev/null
+++ b/elb/src/main/java/org/jclouds/elb/features/SubnetApi.java
@@ -0,0 +1,91 @@
+/*
+ * 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.elb.features;
+
+import static org.jclouds.aws.reference.FormParameters.ACTION;
+
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.aws.filters.FormSigner;
+import org.jclouds.elb.binders.BindSubnetIdsToIndexedFormParams;
+import org.jclouds.elb.xml.MemberResultHandler;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.FormParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.VirtualHost;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+/**
+ * Provides access to Amazon ELB Subnet functionality via the Query API
+ * <p/>
+ * 
+ * @see <a 
href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference";
+ *      >doc</a>
+ */
+@RequestFilters(FormSigner.class)
+@Consumes(MediaType.APPLICATION_XML)
+@VirtualHost
+public interface SubnetApi {
+
+   /**
+    * Attaches subnets to the load balancer.
+    *
+    * @param loadBalancerName Name of the loadBalancer to attach the subnets 
to.
+    * @param subnetIds Collection of subnet IDs to attach.
+    * @return null if load balancer is not found
+    *
+    * @see <a 
href="http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_AttachLoadBalancerToSubnets.html";>doc</a>
+    */
+   @Named("AttachLoadBalancerToSubnets")
+   @POST
+   @Path("/")
+   @XMLResponseParser(MemberResultHandler.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @FormParams(keys = ACTION, values = "AttachLoadBalancerToSubnets")
+   Set<String> attachLoadBalancerToSubnets(
+           @FormParam("LoadBalancerName") String loadBalancerName,
+           @BinderParam(BindSubnetIdsToIndexedFormParams.class) 
Iterable<String> subnetIds);
+
+   /**
+    * Detaches subnets from the load balancer.
+    *
+    * @param loadBalancerName Name of the loadBalancer to detach the subnets 
from.
+    * @param subnetIds Collection of subnet IDs to detach.
+    * @return null if load balancer is not found
+    *
+    * @see <a 
href="http://docs.aws.amazon.com/elasticloadbalancing/2012-06-01/APIReference/API_DetachLoadBalancerFromSubnets.html";>doc</a>
+    */
+   @Named("DetachLoadBalancerFromSubnets")
+   @POST
+   @Path("/")
+   @XMLResponseParser(MemberResultHandler.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @FormParams(keys = ACTION, values = "DetachLoadBalancerFromSubnets")
+   Set<String> detachLoadBalancerFromSubnets(
+           @FormParam("LoadBalancerName") String loadBalancerName,
+           @BinderParam(BindSubnetIdsToIndexedFormParams.class) 
Iterable<String> subnetIds);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/xml/AvailabilityZonesResultHandler.java
----------------------------------------------------------------------
diff --git 
a/elb/src/main/java/org/jclouds/elb/xml/AvailabilityZonesResultHandler.java 
b/elb/src/main/java/org/jclouds/elb/xml/AvailabilityZonesResultHandler.java
deleted file mode 100644
index 2440c18..0000000
--- a/elb/src/main/java/org/jclouds/elb/xml/AvailabilityZonesResultHandler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.elb.xml;
-
-import java.util.Set;
-
-import org.jclouds.http.functions.ParseSax;
-
-import com.google.common.collect.Sets;
-
-public class AvailabilityZonesResultHandler extends 
ParseSax.HandlerWithResult<Set<String>> {
-
-   private Set<String> zones = Sets.newLinkedHashSet();
-   private StringBuilder currentText = new StringBuilder();
-
-   public void endElement(String uri, String localName, String qName) {
-      if (qName.equals("member"))
-         zones.add(currentText.toString().trim());
-      currentText.setLength(0);
-   }
-
-   @Override
-   public Set<String> getResult() {
-      return zones;
-   }
-
-   public void characters(char[] ch, int start, int length) {
-      currentText.append(ch, start, length);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/xml/MemberResultHandler.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/xml/MemberResultHandler.java 
b/elb/src/main/java/org/jclouds/elb/xml/MemberResultHandler.java
new file mode 100644
index 0000000..e72a284
--- /dev/null
+++ b/elb/src/main/java/org/jclouds/elb/xml/MemberResultHandler.java
@@ -0,0 +1,44 @@
+/*
+ * 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.elb.xml;
+
+import java.util.Set;
+
+import org.jclouds.http.functions.ParseSax;
+
+import com.google.common.collect.Sets;
+
+public class MemberResultHandler extends 
ParseSax.HandlerWithResult<Set<String>> {
+
+   private Set<String> members = Sets.newLinkedHashSet();
+   private StringBuilder currentText = new StringBuilder();
+
+   public void endElement(String uri, String localName, String qName) {
+      if (qName.equals("member"))
+         members.add(currentText.toString().trim());
+      currentText.setLength(0);
+   }
+
+   @Override
+   public Set<String> getResult() {
+      return members;
+   }
+
+   public void characters(char[] ch, int start, int length) {
+      currentText.append(ch, start, length);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/main/java/org/jclouds/elb/xml/PolicyHandler.java
----------------------------------------------------------------------
diff --git a/elb/src/main/java/org/jclouds/elb/xml/PolicyHandler.java 
b/elb/src/main/java/org/jclouds/elb/xml/PolicyHandler.java
index 3c5ffb5..6a977a1 100644
--- a/elb/src/main/java/org/jclouds/elb/xml/PolicyHandler.java
+++ b/elb/src/main/java/org/jclouds/elb/xml/PolicyHandler.java
@@ -48,6 +48,7 @@ public class PolicyHandler extends 
ParseSax.HandlerForGeneratedRequestWithResult
       }
    }
 
+
    /**
     * {@inheritDoc}
     */
@@ -59,7 +60,7 @@ public class PolicyHandler extends 
ParseSax.HandlerForGeneratedRequestWithResult
          builder.typeName(currentOrNull(currentText));
       } else if (equalsOrSuffix(qName, "AttributeName")) {
          key = currentOrNull(currentText);
-      } else if (equalsOrSuffix(qName, "AttributeValue")) {
+      } else if (equalsOrSuffix(qName, "AttributeValue") && key != null) {
          String value = currentOrNull(currentText);
          if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value))
             builder.attribute(key, Boolean.valueOf(value));

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiLiveTest.java 
b/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiLiveTest.java
new file mode 100644
index 0000000..9796aa1
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiLiveTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.elb.features;
+
+import static org.assertj.core.util.Preconditions.checkNotNull;
+
+import org.jclouds.elb.domain.HealthCheck;
+import org.jclouds.elb.domain.Listener;
+import org.jclouds.elb.domain.Protocol;
+import org.jclouds.elb.internal.BaseELBApiLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+@Test(groups = "live", testName = "HealthCheckApiLiveTest")
+public class HealthCheckApiLiveTest extends BaseELBApiLiveTest {
+
+   protected HealthCheckApi api() {
+      return api.getHealthCheckApi();
+   }
+
+   @BeforeMethod
+   private void setUp() {
+      super.setup();
+      Listener listener = Listener.builder()
+              .protocol(Protocol.HTTP)
+              .port(80)
+              .instanceProtocol(Protocol.HTTP)
+              .instancePort(80)
+              .build();
+      api.getLoadBalancerApi().createListeningInAvailabilityZones("test", 
listener, ImmutableList.of("us-east-1b"));
+   }
+
+   @AfterClass(alwaysRun = true)
+   @Override
+   protected void tearDown() {
+      super.tearDown();
+      if (api.getLoadBalancerApi().get("test") != null) {
+         api.getLoadBalancerApi().delete("test");
+      }
+   }
+   
+   @Test
+   protected void testConfigureHealthCheck() {
+
+      HealthCheck healthCheck = api().configureHealthCheck("test", 
HealthCheck.builder()
+              .healthyThreshold(2)
+              .unhealthyThreshold(2)
+              .interval(30)
+              .target("HTTP:80/ping")
+              .timeout(3)
+              .build());
+      checkHealthCheck(healthCheck);
+
+   }
+
+   private void checkHealthCheck(HealthCheck healthCheck) {
+      checkNotNull(healthCheck.getHealthyThreshold(), "Description cannot be 
null for InstanceState");
+      checkNotNull(healthCheck.getInterval(), "InstanceId cannot be null for 
InstanceState");
+      checkNotNull(healthCheck.getTarget(), "Target must not be null");
+      checkNotNull(healthCheck.getTimeout(), "State cannot be null for 
InstanceState");
+      checkNotNull(healthCheck.getUnhealthyThreshold(), "Description cannot be 
null for InstanceState");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiMockTest.java 
b/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiMockTest.java
new file mode 100644
index 0000000..343fbae
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/features/HealthCheckApiMockTest.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.elb.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import org.jclouds.elb.domain.HealthCheck;
+import org.jclouds.elb.internal.BaseELBApiMockTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "HealthCheckMockTest", singleThreaded = true)
+public class HealthCheckApiMockTest  extends BaseELBApiMockTest {
+
+    public static final String loadBalancerName = "my-loadbalancer";
+    public static final int healthyThreshold = 2;
+    public static final int unhealthyThreshold = 2;
+    public static final String target = "HTTP:80/ping";
+    public static final int interval = 30;
+    public static final int timeout = 3;
+
+    public void testConfigureHealthCheck() throws InterruptedException {
+        server.enqueue(xmlResponse("/configure_health_check.xml"));
+
+        HealthCheck healthCheck = HealthCheck.builder()
+                .healthyThreshold(healthyThreshold)
+                .unhealthyThreshold(unhealthyThreshold)
+                .target(target)
+                .interval(interval)
+                .timeout(timeout)
+                .build();
+
+        HealthCheck response = 
api.getHealthCheckApi().configureHealthCheck(loadBalancerName, healthCheck);
+
+        assertEquals(response, healthCheck);
+        assertEquals(server.getRequestCount(), 1);
+
+        assertSent(server, "POST", "/");
+    }
+
+    public void testConfigureHealthCheckReturns404() throws 
InterruptedException {
+        server.enqueue(response404());
+
+        HealthCheck healthCheck = HealthCheck.builder()
+                .healthyThreshold(healthyThreshold)
+                .unhealthyThreshold(unhealthyThreshold)
+                .target(target)
+                .interval(interval)
+                .timeout(timeout)
+                .build();
+
+        HealthCheck response = 
api.getHealthCheckApi().configureHealthCheck(loadBalancerName, healthCheck);
+
+        assertNull(response);
+        assertEquals(server.getRequestCount(), 1);
+
+        assertSent(server, "POST", "/");
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/features/PolicyApiLiveTest.java
----------------------------------------------------------------------
diff --git a/elb/src/test/java/org/jclouds/elb/features/PolicyApiLiveTest.java 
b/elb/src/test/java/org/jclouds/elb/features/PolicyApiLiveTest.java
index 9654212..d9b128c 100644
--- a/elb/src/test/java/org/jclouds/elb/features/PolicyApiLiveTest.java
+++ b/elb/src/test/java/org/jclouds/elb/features/PolicyApiLiveTest.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test;
 import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 
-@Test(groups = "live", testName = "PolicyApiLiveTest")
+@Test(groups = "live", testName = "PolicyApiLiveTest", singleThreaded = true)
 public class PolicyApiLiveTest extends BaseELBApiLiveTest {
 
    private void checkPolicy(Policy policy) {
@@ -56,7 +56,6 @@ public class PolicyApiLiveTest extends BaseELBApiLiveTest {
 
    private void checkPolicyType(PolicyType policyType) {
       checkNotNull(policyType.getName(), "Name cannot be null for a 
PolicyType.");
-      checkNotNull(policyType.getDescription(), "Description cannot be null 
for a PolicyType.");
       checkNotNull(policyType.getAttributeMetadata(), "While it is ok to have 
no attributes, the set cannot be null.");
       for (AttributeMetadata<?> attributeMetadata : 
policyType.getAttributeMetadata()) {
          checkAttributeMetadata(attributeMetadata);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/features/SubnetApiLiveTest.java
----------------------------------------------------------------------
diff --git a/elb/src/test/java/org/jclouds/elb/features/SubnetApiLiveTest.java 
b/elb/src/test/java/org/jclouds/elb/features/SubnetApiLiveTest.java
new file mode 100644
index 0000000..6d96d14
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/features/SubnetApiLiveTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.elb.features;
+
+import static org.assertj.core.util.Preconditions.checkNotNull;
+import static org.jclouds.reflect.Reflection2.typeToken;
+
+import java.util.Iterator;
+import java.util.Random;
+import java.util.Set;
+
+import org.jclouds.ContextBuilder;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.compute.EC2ComputeServiceContext;
+import org.jclouds.ec2.domain.Subnet;
+import org.jclouds.elb.domain.Listener;
+import org.jclouds.elb.domain.LoadBalancer;
+import org.jclouds.elb.domain.Protocol;
+import org.jclouds.elb.internal.BaseELBApiLiveTest;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+@Test(groups = "live", testName = "SubnetApiLiveTest")
+public class SubnetApiLiveTest extends BaseELBApiLiveTest {
+   private String loadBalancerName;
+   private EC2Api ec2Api;
+
+
+   @BeforeMethod
+   private void setUp() {
+      super.setup();
+
+      final EC2ComputeServiceContext ec2ComputeServiceContext = 
ContextBuilder.newBuilder("aws-ec2")
+              .credentials(identity, credential)
+              .buildView(typeToken(EC2ComputeServiceContext.class));
+      createTestLoadBalancer();
+
+     ec2Api = ec2ComputeServiceContext.unwrapApi(EC2Api.class);
+
+   }
+
+   private void createTestLoadBalancer (){
+      loadBalancerName = generateRandomName();
+      
api.getLoadBalancerApi().createListeningInAvailabilityZones(loadBalancerName, 
Listener.builder()
+              .protocol(Protocol.HTTP)
+              .port(80)
+              .instanceProtocol(Protocol.HTTP)
+              .instancePort(80)
+              .build(), ImmutableList.of("us-east-1b"));
+   }
+   @AfterMethod(alwaysRun = true)
+   @Override
+   protected void tearDown() {
+      super.tearDown();
+      if (api.getLoadBalancerApi().get(loadBalancerName) != null) {
+         api.getLoadBalancerApi().delete(loadBalancerName);
+      }
+   }
+   protected EC2Api ec2Api() {
+      return ec2Api;
+   }
+   protected SubnetApi subnetApi() {
+      return api.getSubnetApi();
+   }
+
+   @Test
+   protected void testAttachToSubnet() {
+      final LoadBalancer loadBalancer = 
api.getLoadBalancerApi().get(loadBalancerName);
+      final FluentIterable<Subnet> list = ec2Api().getSubnetApi().get().list();
+
+      String subnetIdToAttach = null;
+
+      for (Iterator<Subnet> subnet = list.iterator(); subnet.hasNext();) {
+         Subnet currentSubnet = subnet.next();
+         if (!loadBalancer.getSubnets().contains(currentSubnet.getSubnetId())) 
{
+            subnetIdToAttach = currentSubnet.getSubnetId();
+            break;
+         }
+      }
+
+      checkNotNull(subnetIdToAttach, "Could not find a subnet to attach to the 
load balancer");
+      Assert.assertEquals(1, loadBalancer.getSubnets().size());
+
+      final ImmutableSet<String> subnets = ImmutableSet.<String>builder()
+              .addAll(loadBalancer.getSubnets())
+              .add(subnetIdToAttach)
+              .build();
+
+
+      final Set<String> result = 
subnetApi().attachLoadBalancerToSubnets(loadBalancerName, subnets);
+
+      Assert.assertEquals(result.size(), subnets.size());
+      
Assert.assertEquals(api.getLoadBalancerApi().get(loadBalancerName).getSubnets().size(),
 2);
+
+
+   }
+   @Test
+   protected void testDetachToSubnet() {
+      final LoadBalancer loadBalancer = 
api.getLoadBalancerApi().get(loadBalancerName);
+      final FluentIterable<Subnet> list = ec2Api().getSubnetApi().get().list();
+
+      String subnetIdToAttach = null;
+
+      for (Iterator<Subnet> subnet = list.iterator(); subnet.hasNext();) {
+         Subnet currentSubnet = subnet.next();
+         if (!loadBalancer.getSubnets().contains(currentSubnet.getSubnetId())) 
{
+            subnetIdToAttach = currentSubnet.getSubnetId();
+            break;
+         }
+      }
+
+      checkNotNull(subnetIdToAttach, "Could not find a subnet to attach to the 
load balancer");
+      Assert.assertEquals(1, loadBalancer.getSubnets().size());
+
+      final ImmutableSet<String> subnets = ImmutableSet.<String>builder()
+              .addAll(loadBalancer.getSubnets())
+              .add(subnetIdToAttach)
+              .build();
+
+
+      final Set<String> resultOfAttach = 
subnetApi().attachLoadBalancerToSubnets(loadBalancerName, subnets);
+
+      Assert.assertEquals(resultOfAttach.size(), subnets.size());
+      
Assert.assertEquals(api.getLoadBalancerApi().get(loadBalancerName).getSubnets().size(),
 2);
+
+      final Set<String> resultOfDetach = 
subnetApi().detachLoadBalancerFromSubnets(loadBalancerName, 
ImmutableSet.of(subnetIdToAttach));
+
+      Assert.assertEquals(resultOfDetach.size(), 1);
+      
Assert.assertEquals(api.getLoadBalancerApi().get(loadBalancerName).getSubnets().size(),
 1);
+
+   }
+
+   private String generateRandomName() {
+      return String.format("%s-%s",  "test", new Random().nextInt(10));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/features/SubnetApiMockTest.java
----------------------------------------------------------------------
diff --git a/elb/src/test/java/org/jclouds/elb/features/SubnetApiMockTest.java 
b/elb/src/test/java/org/jclouds/elb/features/SubnetApiMockTest.java
new file mode 100644
index 0000000..fe49a2e
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/features/SubnetApiMockTest.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.elb.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.jclouds.elb.internal.BaseELBApiMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+@Test(groups = "unit", testName = "SubnetMockTest", singleThreaded = true)
+public class SubnetApiMockTest extends BaseELBApiMockTest {
+
+    public static final String loadBalancerName = "my-loadbalancer";
+    public static final String subnetId = "subnet-3561b05e";
+
+    public void testAttachSubnets() throws InterruptedException {
+        server.enqueue(xmlResponse("/attach_load_balancer_to_subnets.xml"));
+
+        Set<String> response = 
api.getSubnetApi().attachLoadBalancerToSubnets(loadBalancerName, 
ImmutableSet.of(subnetId));
+
+        assertTrue(response.contains(subnetId));
+        assertEquals(server.getRequestCount(), 1);
+
+        assertSent(server, "POST", "/");
+    }
+    public void testAttachSubnets404() throws InterruptedException {
+        server.enqueue(response404());
+
+        Set<String> response = 
api.getSubnetApi().attachLoadBalancerToSubnets(loadBalancerName, 
ImmutableSet.of(subnetId));
+
+        assertNull(response);
+        assertEquals(server.getRequestCount(), 1);
+        assertSent(server, "POST", "/");
+    }
+    public void testDetachSubnets() throws InterruptedException {
+        server.enqueue(xmlResponse("/detach_load_balancer_from_subnets.xml"));
+
+        Set<String> response = 
api.getSubnetApi().detachLoadBalancerFromSubnets(loadBalancerName, 
ImmutableSet.of(subnetId));
+
+        assertTrue(response.contains(subnetId));
+        assertEquals(server.getRequestCount(), 1);
+
+        assertSent(server, "POST", "/");
+    }
+    public void testDetachSubnets404() throws InterruptedException {
+        server.enqueue(response404());
+
+        Set<String> response = 
api.getSubnetApi().detachLoadBalancerFromSubnets(loadBalancerName, 
ImmutableSet.of(subnetId));
+
+        assertNull(response);
+        assertEquals(server.getRequestCount(), 1);
+        assertSent(server, "POST", "/");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/internal/BaseELBApiMockTest.java
----------------------------------------------------------------------
diff --git a/elb/src/test/java/org/jclouds/elb/internal/BaseELBApiMockTest.java 
b/elb/src/test/java/org/jclouds/elb/internal/BaseELBApiMockTest.java
new file mode 100644
index 0000000..bd839f1
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/internal/BaseELBApiMockTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.elb.internal;
+
+import static 
com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+
+import org.jclouds.ContextBuilder;
+import org.jclouds.concurrent.config.ExecutorServiceModule;
+import org.jclouds.elb.ELBApi;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Resources;
+import com.google.inject.Module;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+public class BaseELBApiMockTest {
+
+    private static final String MOCK_BEARER_TOKEN = 
"c5401990f0c24135e8d6b5d260603fc71696d4738da9aa04a720229a01a2521d";
+    private static final String DEFAULT_ENDPOINT = "http:";
+    //new AWSELBProviderMetadata().getEndpoint();
+
+    private final Set<Module> modules = ImmutableSet.<Module> of(new 
ExecutorServiceModule(sameThreadExecutor()));
+
+    protected MockWebServer server;
+    protected ELBApi api;
+
+    @BeforeMethod
+    public void start() throws IOException {
+        server = new MockWebServer();
+        server.play();
+        api = ContextBuilder.newBuilder("elb")
+                .credentials("", MOCK_BEARER_TOKEN)
+                .endpoint(url(""))
+                .modules(modules)
+                .overrides(overrides())
+                .buildApi(ELBApi.class);
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void stop() throws IOException {
+        server.shutdown();
+        api.close();
+    }
+
+    protected Properties overrides() {
+        return new Properties();
+    }
+
+    protected String url(String path) {
+        return server.getUrl(path).toString();
+    }
+
+    protected MockResponse xmlResponse(String resource) {
+        return new MockResponse().addHeader("Content-Type", 
"application/xml").setBody(stringFromResource(resource));
+    }
+
+
+    protected String stringFromResource(String resourceName) {
+        try {
+            return Resources.toString(getClass().getResource(resourceName), 
Charsets.UTF_8)
+                    .replace(DEFAULT_ENDPOINT, url(""));
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+    protected MockResponse response404() {
+        return new MockResponse().setStatus("HTTP/1.1 404 Not Found");
+    }
+
+    protected RecordedRequest assertSent(MockWebServer server, String method, 
String path) throws InterruptedException {
+        RecordedRequest request = server.takeRequest();
+        assertEquals(request.getMethod(), method);
+        assertEquals(request.getPath(), path);
+        assertEquals(request.getHeader("Accept"), "application/xml");
+        return request;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/parse/AttachSubnetsResultHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/parse/AttachSubnetsResultHandlerTest.java 
b/elb/src/test/java/org/jclouds/elb/parse/AttachSubnetsResultHandlerTest.java
new file mode 100644
index 0000000..5d3d927
--- /dev/null
+++ 
b/elb/src/test/java/org/jclouds/elb/parse/AttachSubnetsResultHandlerTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.elb.parse;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import org.jclouds.elb.xml.MemberResultHandler;
+import org.jclouds.http.functions.BaseHandlerTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
+@Test(groups = "unit", testName = "AttachSubnetsResultHandlerTest", 
singleThreaded = true)
+public class AttachSubnetsResultHandlerTest extends BaseHandlerTest {
+
+   public void test() {
+      InputStream is = 
getClass().getResourceAsStream("/attach_load_balancer_to_subnets.xml");
+
+      Set<String> expected = expected();
+
+      MemberResultHandler handler = 
injector.getInstance(MemberResultHandler.class);
+      Set<String> result = factory.create(handler).parse(is);
+
+      assertEquals(result.toString(), expected.toString());
+   }
+
+   public Set<String> expected() {
+      return ImmutableSet.of("subnet-3561b05e");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/parse/AvailabilityZonesResultHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/parse/AvailabilityZonesResultHandlerTest.java
 
b/elb/src/test/java/org/jclouds/elb/parse/AvailabilityZonesResultHandlerTest.java
index 8f9a752..cea9e87 100644
--- 
a/elb/src/test/java/org/jclouds/elb/parse/AvailabilityZonesResultHandlerTest.java
+++ 
b/elb/src/test/java/org/jclouds/elb/parse/AvailabilityZonesResultHandlerTest.java
@@ -21,7 +21,7 @@ import static org.testng.Assert.assertEquals;
 import java.io.InputStream;
 import java.util.Set;
 
-import org.jclouds.elb.xml.AvailabilityZonesResultHandler;
+import org.jclouds.elb.xml.MemberResultHandler;
 import org.jclouds.http.functions.BaseHandlerTest;
 import org.testng.annotations.Test;
 
@@ -36,7 +36,7 @@ public class AvailabilityZonesResultHandlerTest extends 
BaseHandlerTest {
 
       Set<String> expected = expected();
 
-      AvailabilityZonesResultHandler handler = 
injector.getInstance(AvailabilityZonesResultHandler.class);
+      MemberResultHandler handler = 
injector.getInstance(MemberResultHandler.class);
       Set<String> result = factory.create(handler).parse(is);
 
       assertEquals(result.toString(), expected.toString());

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/parse/DetachSubnetsResultHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/parse/DetachSubnetsResultHandlerTest.java 
b/elb/src/test/java/org/jclouds/elb/parse/DetachSubnetsResultHandlerTest.java
new file mode 100644
index 0000000..7411dda
--- /dev/null
+++ 
b/elb/src/test/java/org/jclouds/elb/parse/DetachSubnetsResultHandlerTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.elb.parse;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import org.jclouds.elb.xml.MemberResultHandler;
+import org.jclouds.http.functions.BaseHandlerTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
+@Test(groups = "unit", testName = "DetachSubnetsResultHandlerTest")
+public class DetachSubnetsResultHandlerTest extends BaseHandlerTest {
+
+   public void test() {
+      InputStream is = 
getClass().getResourceAsStream("/detach_load_balancer_from_subnets.xml");
+
+      Set<String> expected = expected();
+
+      MemberResultHandler handler = 
injector.getInstance(MemberResultHandler.class);
+      Set<String> result = factory.create(handler).parse(is);
+
+      assertEquals(result.toString(), expected.toString());
+   }
+
+   public Set<String> expected() {
+      return ImmutableSet.of("subnet-3561b05e");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/java/org/jclouds/elb/parse/HealthCheckResultHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/elb/src/test/java/org/jclouds/elb/parse/HealthCheckResultHandlerTest.java 
b/elb/src/test/java/org/jclouds/elb/parse/HealthCheckResultHandlerTest.java
new file mode 100644
index 0000000..12ca527
--- /dev/null
+++ b/elb/src/test/java/org/jclouds/elb/parse/HealthCheckResultHandlerTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.elb.parse;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+
+import org.jclouds.elb.domain.HealthCheck;
+import org.jclouds.elb.xml.HealthCheckHandler;
+import org.jclouds.http.functions.BaseHandlerTest;
+import org.testng.annotations.Test;
+
+// NOTE:without testName, this will not call @Before* and fail w/NPE during 
surefire
+@Test(groups = "unit", testName = "HealthCheckResultHandlerTest")
+public class HealthCheckResultHandlerTest extends BaseHandlerTest {
+
+   public void test() {
+      InputStream is = 
getClass().getResourceAsStream("/configure_health_check.xml");
+
+      HealthCheck expected = expected();
+
+      HealthCheckHandler handler = 
injector.getInstance(HealthCheckHandler.class);
+      HealthCheck result = factory.create(handler).parse(is);
+
+      assertEquals(result.toString(), expected.toString());
+
+   }
+
+   public HealthCheck expected() {
+      return HealthCheck.builder()
+              .healthyThreshold(2)
+              .unhealthyThreshold(2)
+              .target("HTTP:80/ping")
+              .interval(30)
+              .timeout(3)
+              .build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/resources/attach_load_balancer_to_subnets.xml
----------------------------------------------------------------------
diff --git a/elb/src/test/resources/attach_load_balancer_to_subnets.xml 
b/elb/src/test/resources/attach_load_balancer_to_subnets.xml
new file mode 100644
index 0000000..a388dcd
--- /dev/null
+++ b/elb/src/test/resources/attach_load_balancer_to_subnets.xml
@@ -0,0 +1,10 @@
+<AttachLoadBalancerToSubnetsResponse 
xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/";>
+    <AttachLoadBalancerToSubnetsResult>
+        <Subnets>
+            <member>subnet-3561b05e</member>
+        </Subnets>
+    </AttachLoadBalancerToSubnetsResult>
+    <ResponseMetadata>
+        <RequestId>07b1ecbc-1100-11e3-acaf-dd7edEXAMPLE</RequestId>
+    </ResponseMetadata>
+</AttachLoadBalancerToSubnetsResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/resources/configure_health_check.xml
----------------------------------------------------------------------
diff --git a/elb/src/test/resources/configure_health_check.xml 
b/elb/src/test/resources/configure_health_check.xml
new file mode 100644
index 0000000..406b1dc
--- /dev/null
+++ b/elb/src/test/resources/configure_health_check.xml
@@ -0,0 +1,14 @@
+<ConfigureHealthCheckResponse 
xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/";>
+    <ConfigureHealthCheckResult>
+        <HealthCheck>
+            <Interval>30</Interval>
+            <Target>HTTP:80/ping</Target>
+            <HealthyThreshold>2</HealthyThreshold>
+            <Timeout>3</Timeout>
+            <UnhealthyThreshold>2</UnhealthyThreshold>
+        </HealthCheck>
+    </ConfigureHealthCheckResult>
+    <ResponseMetadata>
+        <RequestId>83c88b9d-12b7-11e3-8b82-87b12EXAMPLE</RequestId>
+    </ResponseMetadata>
+</ConfigureHealthCheckResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/elb/src/test/resources/detach_load_balancer_from_subnets.xml
----------------------------------------------------------------------
diff --git a/elb/src/test/resources/detach_load_balancer_from_subnets.xml 
b/elb/src/test/resources/detach_load_balancer_from_subnets.xml
new file mode 100644
index 0000000..53c480a
--- /dev/null
+++ b/elb/src/test/resources/detach_load_balancer_from_subnets.xml
@@ -0,0 +1,10 @@
+<DetachLoadBalancerFromSubnetsResponse 
xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/";>
+    <DetachLoadBalancerFromSubnetsResult>
+        <Subnets>
+            <member>subnet-3561b05e</member>
+        </Subnets>
+    </DetachLoadBalancerFromSubnetsResult>
+    <ResponseMetadata>
+        <RequestId>07b1ecbc-1100-11e3-acaf-dd7edEXAMPLE</RequestId>
+    </ResponseMetadata>
+</DetachLoadBalancerFromSubnetsResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/rds/src/test/java/org/jclouds/rds/features/InstanceApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/rds/src/test/java/org/jclouds/rds/features/InstanceApiLiveTest.java 
b/rds/src/test/java/org/jclouds/rds/features/InstanceApiLiveTest.java
index 92168e4..dfaf086 100644
--- a/rds/src/test/java/org/jclouds/rds/features/InstanceApiLiveTest.java
+++ b/rds/src/test/java/org/jclouds/rds/features/InstanceApiLiveTest.java
@@ -160,7 +160,7 @@ public class InstanceApiLiveTest extends BaseRDSApiLiveTest 
{
    }
 
    @Override
-   @AfterClass(groups = "live")
+   @AfterClass(groups = "live", alwaysRun = true)
    protected void tearDown() {
       try {
          api().delete(INSTANCE);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-aws/blob/e248c37d/rds/src/test/java/org/jclouds/rds/features/SecurityGroupApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/rds/src/test/java/org/jclouds/rds/features/SecurityGroupApiLiveTest.java 
b/rds/src/test/java/org/jclouds/rds/features/SecurityGroupApiLiveTest.java
index 2f523e3..06c094c 100644
--- a/rds/src/test/java/org/jclouds/rds/features/SecurityGroupApiLiveTest.java
+++ b/rds/src/test/java/org/jclouds/rds/features/SecurityGroupApiLiveTest.java
@@ -109,7 +109,7 @@ public class SecurityGroupApiLiveTest extends 
BaseRDSApiLiveTest {
    }
 
    @Override
-   @AfterClass(groups = "live")
+   @AfterClass(groups = "live", alwaysRun = true)
    protected void tearDown() {
       api().delete(SECURITYGROUP);
       super.tearDown();

Reply via email to