Issue 852: added InstanceClient and got live tests passing

This commit is contained in:
Adrian Cole 2012-07-05 23:22:01 -07:00
parent 6359db8c5b
commit 5d30da2908
41 changed files with 1175 additions and 1409 deletions

View File

@ -35,13 +35,13 @@
<properties> <properties>
<test.aws-elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.aws-elb.endpoint> <test.aws-elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.aws-elb.endpoint>
<test.aws-elb.api-version>2010-07-01</test.aws-elb.api-version> <test.aws-elb.api-version>2012-06-01</test.aws-elb.api-version>
<test.aws-elb.build-version></test.aws-elb.build-version> <test.aws-elb.build-version></test.aws-elb.build-version>
<test.aws-elb.identity>${test.aws.identity}</test.aws-elb.identity> <test.aws-elb.identity>${test.aws.identity}</test.aws-elb.identity>
<test.aws-elb.credential>${test.aws.credential}</test.aws-elb.credential> <test.aws-elb.credential>${test.aws.credential}</test.aws-elb.credential>
<test.aws-elb.compute.provider>aws-ec2</test.aws-elb.compute.provider> <test.aws-elb.compute.provider>aws-ec2</test.aws-elb.compute.provider>
<test.aws-elb.compute.endpoint>https://ec2.us-east-1.amazonaws.com</test.aws-elb.compute.endpoint> <test.aws-elb.compute.endpoint></test.aws-elb.compute.endpoint>
<test.aws-elb.compute.api-version>2010-06-15</test.aws-elb.compute.api-version> <test.aws-elb.compute.api-version></test.aws-elb.compute.api-version>
<test.aws-elb.compute.build-version></test.aws-elb.compute.build-version> <test.aws-elb.compute.build-version></test.aws-elb.compute.build-version>
<test.aws-elb.compute.identity>${test.aws.identity}</test.aws-elb.compute.identity> <test.aws-elb.compute.identity>${test.aws.identity}</test.aws-elb.compute.identity>
<test.aws-elb.compute.credential>${test.aws.credential}</test.aws-elb.compute.credential> <test.aws-elb.compute.credential>${test.aws.credential}</test.aws-elb.compute.credential>
@ -94,16 +94,22 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jclouds.driver</groupId> <groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId> <artifactId>jclouds-sshj</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jclouds.driver</groupId> <groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-sshj</artifactId> <artifactId>jclouds-slf4j</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>

View File

@ -1,51 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.elb;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.aws.domain.Region;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBAsyncClientTest;
import org.jclouds.providers.ProviderMetadata;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code ELBAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "AWSELBAsyncClientTest")
public class AWSELBAsyncClientTest extends ELBAsyncClientTest {
public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("describeLoadBalancersInRegion", String.class, String[].class);
for (String region : Region.DEFAULT_REGIONS) {
processor.createRequest(method, region);
}
}
@Override
public ProviderMetadata createProviderMetadata() {
return new AWSELBProviderMetadata();
}
}

View File

@ -1,59 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.elb;
import org.jclouds.aws.domain.Region;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient;
import org.jclouds.elb.ELBClientLiveTest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code ELBClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", singleThreaded = true, testName = "AWSELBClientLiveTest")
public class AWSELBClientLiveTest extends ELBClientLiveTest<ELBClient, ELBAsyncClient> {
public AWSELBClientLiveTest() {
provider = "aws-elb";
}
@Test
public void testCreateLoadBalancer() {
for (String region : Region.DEFAULT_REGIONS) {
createLoadBalancerInRegionZone(region, region + "a", name);
}
}
@Test(dependsOnMethods = "testCreateLoadBalancer")
public void testDescribeLoadBalancers() {
for (String region : Region.DEFAULT_REGIONS) {
describeLoadBalancerInRegion(region);
}
}
@Test(dependsOnMethods = "testDescribeLoadBalancers")
public void testDeleteLoadBalancer() {
for (String region : Region.DEFAULT_REGIONS) {
deleteLoadBalancerInRegion(region);
}
}
}

View File

@ -0,0 +1,35 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.elb.features;
import org.jclouds.elb.features.InstanceClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "AWSInstanceClientLiveTest")
public class AWSInstanceClientLiveTest extends InstanceClientLiveTest {
public AWSInstanceClientLiveTest() {
provider = "aws-elb";
}
}

View File

@ -0,0 +1,35 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.elb.features;
import org.jclouds.elb.features.LoadBalancerClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "AWSLoadBalancerClientLiveTest")
public class AWSLoadBalancerClientLiveTest extends LoadBalancerClientLiveTest {
public AWSLoadBalancerClientLiveTest() {
provider = "aws-elb";
}
}

View File

@ -0,0 +1,35 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.aws.elb.features;
import org.jclouds.elb.features.PolicyClientLiveTest;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "AWSPolicyClientLiveTest")
public class AWSPolicyClientLiveTest extends PolicyClientLiveTest {
public AWSPolicyClientLiveTest() {
provider = "aws-elb";
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.aws.elb.config; package org.jclouds.aws.elb.loadbalancer;
import org.jclouds.elb.loadbalancer.ELBLoadBalancerServiceLiveTest; import org.jclouds.elb.loadbalancer.ELBLoadBalancerServiceLiveTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;

View File

@ -34,15 +34,14 @@
<packaging>bundle</packaging> <packaging>bundle</packaging>
<properties> <properties>
<test.elb.zone>us-east-1a</test.elb.zone>
<test.elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.elb.endpoint> <test.elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.elb.endpoint>
<test.elb.api-version>2012-06-01</test.elb.api-version> <test.elb.api-version>2012-06-01</test.elb.api-version>
<test.elb.build-version></test.elb.build-version> <test.elb.build-version></test.elb.build-version>
<test.elb.identity>${test.aws.identity}</test.elb.identity> <test.elb.identity>${test.aws.identity}</test.elb.identity>
<test.elb.credential>${test.aws.credential}</test.elb.credential> <test.elb.credential>${test.aws.credential}</test.elb.credential>
<test.elb.compute.provider>aws-ec2</test.elb.compute.provider> <test.elb.compute.provider>aws-ec2</test.elb.compute.provider>
<test.elb.compute.endpoint>https://ec2.us-east-1.amazonaws.com</test.elb.compute.endpoint> <test.elb.compute.endpoint></test.elb.compute.endpoint>
<test.elb.compute.api-version>2010-06-15</test.elb.compute.api-version> <test.elb.compute.api-version></test.elb.compute.api-version>
<test.elb.compute.build-version></test.elb.compute.build-version> <test.elb.compute.build-version></test.elb.compute.build-version>
<test.elb.compute.identity>${test.aws.identity}</test.elb.compute.identity> <test.elb.compute.identity>${test.aws.identity}</test.elb.compute.identity>
<test.elb.compute.credential>${test.aws.credential}</test.elb.compute.credential> <test.elb.compute.credential>${test.aws.credential}</test.elb.compute.credential>
@ -128,7 +127,6 @@
</goals> </goals>
<configuration> <configuration>
<systemPropertyVariables> <systemPropertyVariables>
<test.elb.zone>${test.elb.zone}</test.elb.zone>
<test.elb.endpoint>${test.elb.endpoint}</test.elb.endpoint> <test.elb.endpoint>${test.elb.endpoint}</test.elb.endpoint>
<test.elb.api-version>${test.elb.api-version}</test.elb.api-version> <test.elb.api-version>${test.elb.api-version}</test.elb.api-version>
<test.elb.build-version>${test.elb.build-version}</test.elb.build-version> <test.elb.build-version>${test.elb.build-version}</test.elb.build-version>

View File

@ -29,25 +29,19 @@ import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams; import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.elb.binders.BindInstanceIdsToIndexedFormParams; import org.jclouds.elb.features.InstanceAsyncClient;
import org.jclouds.elb.binders.BindLoadBalancerNamesToIndexedFormParams;
import org.jclouds.elb.domain.CrappyLoadBalancer;
import org.jclouds.elb.features.LoadBalancerAsyncClient; import org.jclouds.elb.features.LoadBalancerAsyncClient;
import org.jclouds.elb.features.PolicyAsyncClient; import org.jclouds.elb.features.PolicyAsyncClient;
import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler; import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.elb.xml.DescribeLoadBalancersResponseHandler;
import org.jclouds.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -85,6 +79,12 @@ public interface ELBAsyncClient {
@Delegate @Delegate
PolicyAsyncClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); PolicyAsyncClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides asynchronous access to Instance features.
*/
@Delegate
InstanceAsyncClient getInstanceClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/// old stuff /// old stuff
public static final String VERSION = "2012-06-01"; public static final String VERSION = "2012-06-01";
@ -117,39 +117,4 @@ public interface ELBAsyncClient {
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name); @FormParam("LoadBalancerName") String name);
/**
* @see ELBClient#registerInstancesWithLoadBalancerInRegion
*/
@POST
@Path("/")
@XMLResponseParser(RegisterInstancesWithLoadBalancerResponseHandler.class)
@FormParams(keys = ACTION, values = "RegisterInstancesWithLoadBalancer")
ListenableFuture<Set<String>> registerInstancesWithLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see ELBClient#deregisterInstancesWithLoadBalancerInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeregisterInstancesFromLoadBalancer")
ListenableFuture<Void> deregisterInstancesWithLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see ELBClient#describeLoadBalancersInRegion
*/
@POST
@Path("/")
@XMLResponseParser(DescribeLoadBalancersResponseHandler.class)
@FormParams(keys = ACTION, values = "DescribeLoadBalancers")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<? extends CrappyLoadBalancer>> describeLoadBalancersInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindLoadBalancerNamesToIndexedFormParams.class) String... loadbalancerNames);
} }

View File

@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.features.InstanceClient;
import org.jclouds.elb.features.LoadBalancerClient; import org.jclouds.elb.features.LoadBalancerClient;
import org.jclouds.elb.features.PolicyClient; import org.jclouds.elb.features.PolicyClient;
import org.jclouds.location.Region; import org.jclouds.location.Region;
@ -64,6 +64,12 @@ public interface ELBClient {
*/ */
@Delegate @Delegate
PolicyClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); PolicyClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides synchronous access to Instance features.
*/
@Delegate
InstanceClient getInstanceClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/// old stuff /// old stuff
/** /**
@ -96,42 +102,5 @@ public interface ELBClient {
*/ */
void deleteLoadBalancerInRegion(@Nullable String region, String name); void deleteLoadBalancerInRegion(@Nullable String region, String name);
/**
* Register instances with an existing load balancer
*
* @param name
* Load Balancer name
* @param instanceIds
* Set of instance Ids to register with load balancer
* @return instanceIds registered with load balancer
*
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/2009-05-15/DeveloperGuide/"
*/
Set<String> registerInstancesWithLoadBalancerInRegion(@Nullable String region, String name, String... instanceIds);
/**
* Deregister instances with an existing load balancer
*
* @param name
* Load Balancer name
* @param instanceIds
* Set of instance Ids to deregister with load balancer
* @return
*
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/2009-05-15/DeveloperGuide/"
*/
void deregisterInstancesWithLoadBalancerInRegion(@Nullable String region, String name, String... instanceIds);
/**
* Returns a set of elastic load balancers
*
* @param region
* @param loadbalancerNames
* names associated with the LoadBalancers at creation time.
* @return
*/
Set<? extends CrappyLoadBalancer> describeLoadBalancersInRegion(@Nullable String region, String... loadbalancerNames);
} }

View File

@ -18,15 +18,19 @@
*/ */
package org.jclouds.elb.binders; package org.jclouds.elb.binders;
import static org.jclouds.aws.util.AWSUtils.indexStringArrayToFormValuesWithStringFormat; import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.rest.Binder; import org.jclouds.rest.Binder;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
/** /**
* Binds the String [] to form parameters named with InstanceId.index * Binds the Iterable<String> to form parameters named with Instances.member.index.InstanceId
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -34,7 +38,14 @@ import org.jclouds.rest.Binder;
public class BindInstanceIdsToIndexedFormParams implements Binder { public class BindInstanceIdsToIndexedFormParams implements Binder {
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) { public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return indexStringArrayToFormValuesWithStringFormat(request, "Instances.member.%s.InstanceId", input); Iterable<?> values = Iterable.class.cast(checkNotNull(input, "instanceIds"));
Builder<String, String> builder = ImmutableMultimap.builder();
int i = 0;
for (Object o : values) {
builder.put("Instances.member." + (i++ + 1) + ".InstanceId", o.toString());
}
ImmutableMultimap<String, String> forms = builder.build();
return forms.size() == 0 ? request : ModifyRequest.putFormParams(request, forms);
} }
} }

View File

@ -23,6 +23,8 @@ import java.util.Map;
import org.jclouds.aws.config.FormSigningRestClientModule; import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient; import org.jclouds.elb.ELBClient;
import org.jclouds.elb.features.InstanceAsyncClient;
import org.jclouds.elb.features.InstanceClient;
import org.jclouds.elb.features.LoadBalancerAsyncClient; import org.jclouds.elb.features.LoadBalancerAsyncClient;
import org.jclouds.elb.features.LoadBalancerClient; import org.jclouds.elb.features.LoadBalancerClient;
import org.jclouds.elb.features.PolicyAsyncClient; import org.jclouds.elb.features.PolicyAsyncClient;
@ -42,6 +44,7 @@ public class ELBRestClientModule extends FormSigningRestClientModule<ELBClient,
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()// public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(LoadBalancerClient.class, LoadBalancerAsyncClient.class) .put(LoadBalancerClient.class, LoadBalancerAsyncClient.class)
.put(PolicyClient.class, PolicyAsyncClient.class) .put(PolicyClient.class, PolicyAsyncClient.class)
.put(InstanceClient.class, InstanceAsyncClient.class)
.build(); .build();
public ELBRestClientModule() { public ELBRestClientModule() {

View File

@ -1,447 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.domain;
import java.util.HashSet;
import java.util.Set;
import com.google.common.annotations.Beta;
/**
*
*
* @author Lili Nader
*/
@Beta
// Missing fields, this class is too big, please cut out inner classes into top-level
@Deprecated
public class CrappyLoadBalancer implements Comparable<CrappyLoadBalancer> {
// Missing: createdTime, healthcheck
private String region;
private String name;
private Set<String> instanceIds;
private Set<String> availabilityZones;
private String dnsName;
// TODO: this could be cleaned up to be a policy collection of subclasses of Policy. note that
// docs suggest there could be many
private AppCookieStickinessPolicy appCookieStickinessPolicy;
private LBCookieStickinessPolicy lBCookieStickinessPolicy;
private Set<LoadBalancerListener> loadBalancerListeners;
public CrappyLoadBalancer() {
super();
this.instanceIds = new HashSet<String>();
this.availabilityZones = new HashSet<String>();
this.loadBalancerListeners = new HashSet<LoadBalancerListener>();
}
public CrappyLoadBalancer(String region, String name, Set<String> instanceIds, Set<String> availabilityZones,
String dnsName) {
this.region = region;
this.name = name;
this.instanceIds = instanceIds;
this.availabilityZones = availabilityZones;
this.dnsName = dnsName;
this.loadBalancerListeners = new HashSet<LoadBalancerListener>();
}
public void setRegion(String region) {
this.region = region;
}
public void setName(String name) {
this.name = name;
}
public void setInstanceIds(Set<String> instanceIds) {
this.instanceIds = instanceIds;
}
public void setAvailabilityZones(Set<String> availabilityZones) {
this.availabilityZones = availabilityZones;
}
public void setDnsName(String dnsName) {
this.dnsName = dnsName;
}
public void setAppCookieStickinessPolicy(AppCookieStickinessPolicy appCookieStickinessPolicy) {
this.appCookieStickinessPolicy = appCookieStickinessPolicy;
}
public void setlBCookieStickinessPolicy(LBCookieStickinessPolicy lBCookieStickinessPolicy) {
this.lBCookieStickinessPolicy = lBCookieStickinessPolicy;
}
public void setLoadBalancerListeners(Set<LoadBalancerListener> loadBalancerListeners) {
this.loadBalancerListeners = loadBalancerListeners;
}
public String getName() {
return name;
}
public Set<String> getInstanceIds() {
return instanceIds;
}
public Set<String> getAvailabilityZones() {
return availabilityZones;
}
public String getDnsName() {
return dnsName;
}
public AppCookieStickinessPolicy getAppCookieStickinessPolicy() {
return appCookieStickinessPolicy;
}
public LBCookieStickinessPolicy getlBCookieStickinessPolicy() {
return lBCookieStickinessPolicy;
}
public Set<LoadBalancerListener> getLoadBalancerListeners() {
return loadBalancerListeners;
}
public String getRegion() {
return region;
}
@Override
public int compareTo(CrappyLoadBalancer that) {
return name.compareTo(that.name);
}
@Override
public String toString() {
return "[region=" + region + ", name=" + name + ", instanceIds=" + instanceIds + ", availabilityZones="
+ availabilityZones + ", dnsName=" + dnsName + ", appCookieStickinessPolicy="
+ appCookieStickinessPolicy + ", lBCookieStickinessPolicy=" + lBCookieStickinessPolicy
+ ", loadBalancerListeners=" + loadBalancerListeners + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((appCookieStickinessPolicy == null) ? 0 : appCookieStickinessPolicy.hashCode());
result = prime * result + ((availabilityZones == null) ? 0 : availabilityZones.hashCode());
result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode());
result = prime * result + ((instanceIds == null) ? 0 : instanceIds.hashCode());
result = prime * result + ((lBCookieStickinessPolicy == null) ? 0 : lBCookieStickinessPolicy.hashCode());
result = prime * result + ((loadBalancerListeners == null) ? 0 : loadBalancerListeners.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CrappyLoadBalancer other = (CrappyLoadBalancer) obj;
if (appCookieStickinessPolicy == null) {
if (other.appCookieStickinessPolicy != null)
return false;
} else if (!appCookieStickinessPolicy.equals(other.appCookieStickinessPolicy))
return false;
if (availabilityZones == null) {
if (other.availabilityZones != null)
return false;
} else if (!availabilityZones.equals(other.availabilityZones))
return false;
if (dnsName == null) {
if (other.dnsName != null)
return false;
} else if (!dnsName.equals(other.dnsName))
return false;
if (instanceIds == null) {
if (other.instanceIds != null)
return false;
} else if (!instanceIds.equals(other.instanceIds))
return false;
if (lBCookieStickinessPolicy == null) {
if (other.lBCookieStickinessPolicy != null)
return false;
} else if (!lBCookieStickinessPolicy.equals(other.lBCookieStickinessPolicy))
return false;
if (loadBalancerListeners == null) {
if (other.loadBalancerListeners != null)
return false;
} else if (!loadBalancerListeners.equals(other.loadBalancerListeners))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
return true;
}
public static class AppCookieStickinessPolicy {
private String policyName;
private String cookieName;
public AppCookieStickinessPolicy() {
super();
}
public AppCookieStickinessPolicy(String policyName, String cookieName) {
super();
this.policyName = policyName;
this.cookieName = cookieName;
}
public String getPolicyName() {
return policyName;
}
public String getCookieName() {
return cookieName;
}
public void setPolicyName(String policyName) {
this.policyName = policyName;
}
public void setCookieName(String cookieName) {
this.cookieName = cookieName;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cookieName == null) ? 0 : cookieName.hashCode());
result = prime * result + ((policyName == null) ? 0 : policyName.hashCode());
return result;
}
@Override
public String toString() {
return "[policyName=" + policyName + ", cookieName=" + cookieName + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AppCookieStickinessPolicy other = (AppCookieStickinessPolicy) obj;
if (cookieName == null) {
if (other.cookieName != null)
return false;
} else if (!cookieName.equals(other.cookieName))
return false;
if (policyName == null) {
if (other.policyName != null)
return false;
} else if (!policyName.equals(other.policyName))
return false;
return true;
}
}
public static class LBCookieStickinessPolicy {
private String policyName;
private Integer cookieExpirationPeriod;
public LBCookieStickinessPolicy() {
super();
}
public LBCookieStickinessPolicy(String policyName, Integer cookieExpirationPeriod) {
super();
this.policyName = policyName;
this.cookieExpirationPeriod = cookieExpirationPeriod;
}
public String getPolicyName() {
return policyName;
}
public Integer getCookieExpirationPeriod() {
return cookieExpirationPeriod;
}
public void setPolicyName(String policyName) {
this.policyName = policyName;
}
public void setCookieExpirationPeriod(Integer cookieExpirationPeriod) {
this.cookieExpirationPeriod = cookieExpirationPeriod;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cookieExpirationPeriod == null) ? 0 : cookieExpirationPeriod.hashCode());
result = prime * result + ((policyName == null) ? 0 : policyName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LBCookieStickinessPolicy other = (LBCookieStickinessPolicy) obj;
if (cookieExpirationPeriod == null) {
if (other.cookieExpirationPeriod != null)
return false;
} else if (!cookieExpirationPeriod.equals(other.cookieExpirationPeriod))
return false;
if (policyName == null) {
if (other.policyName != null)
return false;
} else if (!policyName.equals(other.policyName))
return false;
return true;
}
@Override
public String toString() {
return "[policyName=" + policyName + ", cookieExpirationPeriod=" + cookieExpirationPeriod + "]";
}
}
public static class LoadBalancerListener {
// TODO: missing SSLCertificateId
private Set<String> policyNames;
private Integer instancePort;
private Integer loadBalancerPort;
private String protocol;
public LoadBalancerListener(Set<String> policyNames, Integer instancePort, Integer loadBalancerPort,
String protocol) {
super();
this.policyNames = policyNames;
this.instancePort = instancePort;
this.loadBalancerPort = loadBalancerPort;
this.protocol = protocol;
}
public LoadBalancerListener() {
super();
}
public Set<String> getPolicyNames() {
return policyNames;
}
public Integer getInstancePort() {
return instancePort;
}
public Integer getLoadBalancerPort() {
return loadBalancerPort;
}
public String getProtocol() {
return protocol;
}
public void setPolicyNames(Set<String> policyNames) {
this.policyNames = policyNames;
}
public void setInstancePort(Integer instancePort) {
this.instancePort = instancePort;
}
public void setLoadBalancerPort(Integer loadBalancerPort) {
this.loadBalancerPort = loadBalancerPort;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((instancePort == null) ? 0 : instancePort.hashCode());
result = prime * result + ((loadBalancerPort == null) ? 0 : loadBalancerPort.hashCode());
result = prime * result + ((policyNames == null) ? 0 : policyNames.hashCode());
result = prime * result + ((protocol == null) ? 0 : protocol.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LoadBalancerListener other = (LoadBalancerListener) obj;
if (instancePort == null) {
if (other.instancePort != null)
return false;
} else if (!instancePort.equals(other.instancePort))
return false;
if (loadBalancerPort == null) {
if (other.loadBalancerPort != null)
return false;
} else if (!loadBalancerPort.equals(other.loadBalancerPort))
return false;
if (policyNames == null) {
if (other.policyNames != null)
return false;
} else if (!policyNames.equals(other.policyNames))
return false;
if (protocol == null) {
if (other.protocol != null)
return false;
} else if (!protocol.equals(other.protocol))
return false;
return true;
}
@Override
public String toString() {
return "[policyNames=" + policyNames + ", instancePort=" + instancePort + ", loadBalancerPort="
+ loadBalancerPort + ", protocol=" + protocol + "]";
}
}
}

View File

@ -0,0 +1,168 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
/**
* the current state of an instance in a loadbalancer.
*
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference/API_InstanceState.html"
* >doc</a>
*
* @author Adrian Cole
*/
public class InstanceState {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().fromAttributeMetadata(this);
}
public static class Builder {
protected String description;
protected String instanceId;
protected Optional<String> reasonCode = Optional.absent();
protected String state;
/**
* @see InstanceState#getDescription()
*/
public Builder description(String description) {
this.description = description;
return this;
}
/**
* @see InstanceState#getInstanceId()
*/
public Builder instanceId(String instanceId) {
this.instanceId = instanceId;
return this;
}
/**
* @see InstanceState#getReasonCode()
*/
public Builder reasonCode(String reasonCode) {
this.reasonCode = Optional.fromNullable(reasonCode);
return this;
}
/**
* @see InstanceState#getState()
*/
public Builder state(String state) {
this.state = state;
return this;
}
public InstanceState build() {
return new InstanceState(description, instanceId, reasonCode, state);
}
public Builder fromAttributeMetadata(InstanceState in) {
return this.description(in.getDescription()).instanceId(in.getInstanceId())
.reasonCode(in.getReasonCode().orNull()).state(in.getState());
}
}
protected final String description;
protected final String instanceId;
protected final Optional<String> reasonCode;
protected final String state;
protected InstanceState(String description, String instanceId, Optional<String> reasonCode, String state) {
this.description = checkNotNull(description, "description");
this.instanceId = checkNotNull(instanceId, "instanceId");
this.reasonCode = checkNotNull(reasonCode, "reasonCode");
this.state = checkNotNull(state, "state");
}
/**
* Provides a description of the instance.
*/
public String getDescription() {
return description;
}
/**
* Provides an EC2 instance ID.
*/
public String getInstanceId() {
return instanceId;
}
/**
* Provides information about the cause of OutOfService instances. Specifically, it indicates
* whether the cause is Elastic Load Balancing or the instance behind the LoadBalancer.
*/
public Optional<String> getReasonCode() {
return reasonCode;
}
/**
* Specifies the current status of the instance.
*/
public String getState() {
return state;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(description, instanceId, reasonCode, state);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
InstanceState other = InstanceState.class.cast(obj);
return Objects.equal(this.description, other.description) && Objects.equal(this.instanceId, other.instanceId)
&& Objects.equal(this.reasonCode, other.reasonCode) && Objects.equal(this.state, other.state);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("description", description)
.add("instanceId", instanceId).add("reasonCode", reasonCode.orNull()).add("state", state).toString();
}
}

View File

@ -105,6 +105,7 @@ public class LoadBalancer {
protected HealthCheck healthCheck; protected HealthCheck healthCheck;
protected ImmutableSet.Builder<String> instanceIds = ImmutableSet.<String> builder(); protected ImmutableSet.Builder<String> instanceIds = ImmutableSet.<String> builder();
protected ImmutableSet.Builder<ListenerWithPolicies> listeners = ImmutableSet.<ListenerWithPolicies> builder(); protected ImmutableSet.Builder<ListenerWithPolicies> listeners = ImmutableSet.<ListenerWithPolicies> builder();
protected ImmutableSet.Builder<String> availabilityZones = ImmutableSet.<String> builder();
protected Optional<Scheme> scheme = Optional.absent(); protected Optional<Scheme> scheme = Optional.absent();
protected Optional<String> VPCId = Optional.absent(); protected Optional<String> VPCId = Optional.absent();
@ -172,6 +173,22 @@ public class LoadBalancer {
return self(); return self();
} }
/**
* @see LoadBalancer#getAvailabilityZones()
*/
public T availabilityZones(Iterable<String> availabilityZones) {
this.availabilityZones.addAll(checkNotNull(availabilityZones, "availabilityZones"));
return self();
}
/**
* @see LoadBalancer#getAvailabilityZones()
*/
public T availabilityZone(String availabilityZone) {
this.availabilityZones.add(checkNotNull(availabilityZone, "availabilityZone"));
return self();
}
/** /**
* @see LoadBalancer#getScheme() * @see LoadBalancer#getScheme()
*/ */
@ -190,13 +207,14 @@ public class LoadBalancer {
public LoadBalancer build() { public LoadBalancer build() {
return new LoadBalancer(name, createdTime, dnsName, healthCheck, instanceIds.build(), listeners.build(), return new LoadBalancer(name, createdTime, dnsName, healthCheck, instanceIds.build(), listeners.build(),
scheme, VPCId); availabilityZones.build(), scheme, VPCId);
} }
public T fromLoadBalancer(LoadBalancer in) { public T fromLoadBalancer(LoadBalancer in) {
return this.name(in.getName()).createdTime(in.getCreatedTime()).dnsName(in.getDnsName()) return this.name(in.getName()).createdTime(in.getCreatedTime()).dnsName(in.getDnsName())
.healthCheck(in.getHealthCheck()).listeners(in.getListeners()).instanceIds(in.getInstanceIds()) .healthCheck(in.getHealthCheck()).listeners(in.getListeners()).instanceIds(in.getInstanceIds())
.scheme(in.getScheme().orNull()).VPCId(in.getVPCId().orNull()); .availabilityZones(in.getAvailabilityZones()).scheme(in.getScheme().orNull())
.VPCId(in.getVPCId().orNull());
} }
} }
@ -213,18 +231,20 @@ public class LoadBalancer {
protected final HealthCheck healthCheck; protected final HealthCheck healthCheck;
protected final Set<String> instanceIds; protected final Set<String> instanceIds;
protected final Set<ListenerWithPolicies> listeners; protected final Set<ListenerWithPolicies> listeners;
protected final Set<String> availabilityZones;
protected final Optional<Scheme> scheme; protected final Optional<Scheme> scheme;
protected final Optional<String> VPCId; protected final Optional<String> VPCId;
protected LoadBalancer(String name, Date createdTime, String dnsName, HealthCheck healthCheck, protected LoadBalancer(String name, Date createdTime, String dnsName, HealthCheck healthCheck,
Iterable<String> instanceIds, Iterable<ListenerWithPolicies> listeners, Optional<Scheme> scheme, Iterable<String> instanceIds, Iterable<ListenerWithPolicies> listeners, Iterable<String> availabilityZones,
Optional<String> VPCId) { Optional<Scheme> scheme, Optional<String> VPCId) {
this.name = checkNotNull(name, "name"); this.name = checkNotNull(name, "name");
this.createdTime = checkNotNull(createdTime, "createdTime"); this.createdTime = checkNotNull(createdTime, "createdTime");
this.dnsName = checkNotNull(dnsName, "dnsName"); this.dnsName = checkNotNull(dnsName, "dnsName");
this.healthCheck = checkNotNull(healthCheck, "healthCheck"); this.healthCheck = checkNotNull(healthCheck, "healthCheck");
this.instanceIds = ImmutableSet.copyOf(checkNotNull(instanceIds, "instanceIds")); this.instanceIds = ImmutableSet.copyOf(checkNotNull(instanceIds, "instanceIds"));
this.listeners = ImmutableSet.copyOf(checkNotNull(listeners, "listeners")); this.listeners = ImmutableSet.copyOf(checkNotNull(listeners, "listeners"));
this.availabilityZones = ImmutableSet.copyOf(checkNotNull(availabilityZones, "availabilityZones"));
this.scheme = checkNotNull(scheme, "scheme"); this.scheme = checkNotNull(scheme, "scheme");
this.VPCId = checkNotNull(VPCId, "VPCId"); this.VPCId = checkNotNull(VPCId, "VPCId");
} }
@ -272,6 +292,13 @@ public class LoadBalancer {
return listeners; return listeners;
} }
/**
* Specifies a list of Availability Zones.
*/
public Set<String> getAvailabilityZones() {
return availabilityZones;
}
/** /**
* Type of the loadbalancer; This option is only available for LoadBalancers attached to an * Type of the loadbalancer; This option is only available for LoadBalancers attached to an
* Amazon VPC. * Amazon VPC.
@ -315,9 +342,10 @@ public class LoadBalancer {
*/ */
@Override @Override
public String toString() { public String toString() {
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("createdTime", createdTime).add( return Objects.toStringHelper(this).omitNullValues().add("name", name).add("createdTime", createdTime)
"dnsName", dnsName).add("healthCheck", healthCheck).add("instanceIds", instanceIds).add("listeners", .add("dnsName", dnsName).add("healthCheck", healthCheck).add("instanceIds", instanceIds)
listeners).add("scheme", scheme.orNull()).add("VPCId", VPCId.orNull()).toString(); .add("listeners", listeners).add("availabilityZones", availabilityZones).add("scheme", scheme.orNull())
.add("VPCId", VPCId.orNull()).toString();
} }
} }

View File

@ -20,10 +20,15 @@ package org.jclouds.elb.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.base.Function;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
/** /**
* *
@ -129,6 +134,21 @@ public class PolicyType {
public Set<AttributeMetadata<?>> getAttributeMetadata() { public Set<AttributeMetadata<?>> getAttributeMetadata() {
return attributeMetadata; return attributeMetadata;
} }
/**
* convenience method
* @see #getAttributeMetadata()
*/
public Map<String, AttributeMetadata<?>> getAttributeMetadataByName() {
return Maps.uniqueIndex(attributeMetadata, new Function<AttributeMetadata<?>, String>(){
@Override
public String apply(@Nullable AttributeMetadata<?> input) {
return input.getName();
}
});
}
/** /**
* {@inheritDoc} * {@inheritDoc}

View File

@ -0,0 +1,30 @@
package org.jclouds.elb.domain.regionscoped;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.elb.domain.LoadBalancer;
/**
* @author Adrian Cole
*/
public class LoadBalancerInRegion extends RegionAndName {
protected final LoadBalancer loadBalancer;
public LoadBalancerInRegion(LoadBalancer loadBalancer, String regionId) {
super(regionId, checkNotNull(loadBalancer, "loadBalancer").getName());
this.loadBalancer = loadBalancer;
}
public LoadBalancer getLoadBalancer() {
return loadBalancer;
}
// superclass hashCode/equals are good enough, and help us use RegionAndId and LoadBalancerInRegion
// interchangeably as Map keys
@Override
public String toString() {
return "[loadBalancer=" + loadBalancer + ", regionId=" + regionId + "]";
}
}

View File

@ -0,0 +1,88 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.domain.regionscoped;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
public class RegionAndName {
public static RegionAndName fromSlashEncoded(String name) {
Iterable<String> parts = Splitter.on('/').split(checkNotNull(name, "name"));
checkArgument(Iterables.size(parts) == 2, "name must be in format regionId/name");
return new RegionAndName(Iterables.get(parts, 0), Iterables.get(parts, 1));
}
public static RegionAndName fromRegionAndName(String regionId, String name) {
return new RegionAndName(regionId, name);
}
private static String slashEncodeRegionAndName(String regionId, String name) {
return checkNotNull(regionId, "regionId") + "/" + checkNotNull(name, "name");
}
public String slashEncode() {
return slashEncodeRegionAndName(regionId, name);
}
protected final String regionId;
protected final String name;
protected RegionAndName(String regionId, String name) {
this.regionId = checkNotNull(regionId, "regionId");
this.name = checkNotNull(name, "name");
}
@Override
public int hashCode() {
return Objects.hashCode(regionId, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RegionAndName other = (RegionAndName) obj;
return Objects.equal(regionId, other.regionId) && Objects.equal(name, other.name);
}
public String getRegion() {
return regionId;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "[regionId=" + regionId + ", name=" + name + "]";
}
}

View File

@ -0,0 +1,104 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.features;
import static org.jclouds.aws.reference.FormParameters.ACTION;
import java.util.Set;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.elb.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.elb.domain.InstanceState;
import org.jclouds.elb.xml.DescribeLoadBalancerPoliciesResultHandler;
import org.jclouds.elb.xml.InstancesResultHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
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 org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Amazon ELB via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference"
* >doc</a>
* @see InstanceClient
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface InstanceAsyncClient {
/**
* @see InstanceClient#listInstanceStatesOfLoadBalancer(String)
*/
@POST
@Path("/")
@XMLResponseParser(DescribeLoadBalancerPoliciesResultHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@FormParams(keys = "Action", values = "DescribeInstanceHealth")
ListenableFuture<Set<InstanceState>> listInstanceStatesOfLoadBalancer(
@FormParam("LoadBalancerName") String loadBalancerName);
/**
* @see InstanceClient#listInstanceStatesOfLoadBalancer(Iterable<String>, String)
*/
@POST
@Path("/")
@XMLResponseParser(DescribeLoadBalancerPoliciesResultHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@FormParams(keys = "Action", values = "DescribeInstanceHealth")
ListenableFuture<Set<InstanceState>> listInstanceStatesOfLoadBalancer(
@BinderParam(BindInstanceIdsToIndexedFormParams.class) Iterable<String> instanceIds,
@FormParam("LoadBalancerName") String loadBalancerName);
/**
* @see InstanceClient#registerInstancesWithLoadBalancer
*/
@POST
@Path("/")
@XMLResponseParser(InstancesResultHandler.class)
@FormParams(keys = ACTION, values = "RegisterInstancesWithLoadBalancer")
ListenableFuture<Set<String>> registerInstancesWithLoadBalancer(
@BinderParam(BindInstanceIdsToIndexedFormParams.class) Iterable<String> instanceIds,
@FormParam("LoadBalancerName") String loadBalancerName);
/**
* @see InstanceClient#deregisterInstancesFromLoadBalancer
*/
@POST
@Path("/")
@XMLResponseParser(InstancesResultHandler.class)
@FormParams(keys = ACTION, values = "DeregisterInstancesFromLoadBalancer")
ListenableFuture<Set<String>> deregisterInstancesFromLoadBalancer(
@BinderParam(BindInstanceIdsToIndexedFormParams.class) Iterable<String> instanceIds,
@FormParam("LoadBalancerName") String loadBalancerName);
}

View File

@ -0,0 +1,131 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.elb.domain.InstanceState;
/**
* Provides access to Amazon ELB via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference" />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface InstanceClient {
/**
* Returns the current state of the instances of the specified LoadBalancer.
*
* <h4>Note</h4>
*
* The client must have created the specified input LoadBalancer in order to retrieve this
* information; the client must provide the same account credentials as those that were used to
* create the LoadBalancer.
*
* @param loadBalancerName
* The name associated with the LoadBalancer. The name must be unique within the client
* AWS account.
*
* @return state of all instances of the load balancer
*/
Set<InstanceState> listInstanceStatesOfLoadBalancer(String loadBalancerName);
/**
* Returns the current state of the instances of the specified LoadBalancer.
*
* <h4>Note</h4>
*
* The client must have created the specified input LoadBalancer in order to retrieve this
* information; the client must provide the same account credentials as those that were used to
* create the LoadBalancer.
*
* @param instanceIds
* A list of instance IDs whose states are being queried.
* @param loadBalancerName
* The name associated with the LoadBalancer. The name must be unique within the client
* AWS account.
*
* @return state of all instances of the load balancer
*/
Set<InstanceState> listInstanceStatesOfLoadBalancer(Iterable<String> instanceIds, String loadBalancerName);
/**
* Adds new instances to the LoadBalancer.
*
* Once the instance is registered, it starts receiving traffic and requests from the
* LoadBalancer. Any instance that is not in any of the Availability Zones registered for the
* LoadBalancer will be moved to the OutOfService state. It will move to the InService state when
* the Availability Zone is added to the LoadBalancer.
*
* <h4>Note</h4>
*
* In order for this call to be successful, the client must have created the LoadBalancer. The
* client must provide the same account credentials as those that were used to create the
* LoadBalancer.
*
* <h4>Note</h4>
*
* Completion of this API does not guarantee that operation has completed. Rather, it means that
* the request has been registered and the changes will happen shortly.
*
* @param instanceIds
* A list of instance IDs that should be registered with the LoadBalancer.
*
* <h4>Note</h4>
*
* When the instance is stopped and then restarted, the IP addresses associated with
* your instance changes. Elastic Load Balancing cannot recognize the new IP address,
* which prevents it from routing traffic to your instances. We recommend that you
* de-register your Amazon EC2 instances from your load balancer after you stop your
* instance, and then register the load balancer with your instance after you've
* restarted. To de-register your instances from load balancer, use
* DeregisterInstancesFromLoadBalancer action.
*
*
* @param loadBalancerName
* The name associated with the LoadBalancer. The name must be unique within the client
* AWS account.
*
* @return instanceIds registered with load balancer
*/
Set<String> registerInstancesWithLoadBalancer(Iterable<String> instanceIds, String loadBalancerName);
/**
* Deregisters instances from the LoadBalancer. Once the instance is deregistered, it will stop
* receiving traffic from the LoadBalancer.
*
* In order to successfully call this API, the same account credentials as those used to create
* the LoadBalancer must be provided.
*
* @param instanceIds
* A list of EC2 instance IDs consisting of all instances to be deregistered.
*
* @param loadBalancerName
* The name associated with the LoadBalancer. The name must be unique within the client
* AWS account.
*
* @return instanceIds still registered with load balancer
*/
Set<String> deregisterInstancesFromLoadBalancer(Iterable<String> instanceIds, String loadBalancerName);
}

View File

@ -18,7 +18,7 @@
*/ */
package org.jclouds.elb.loadbalancer.config; package org.jclouds.elb.loadbalancer.config;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.elb.loadbalancer.functions.LoadBalancerToLoadBalancerMetadata; import org.jclouds.elb.loadbalancer.functions.LoadBalancerToLoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
@ -34,7 +34,7 @@ public class ELBLoadBalancerServiceDependenciesModule extends AbstractModule {
@Override @Override
protected void configure() { protected void configure() {
bind(new TypeLiteral<Function<CrappyLoadBalancer, LoadBalancerMetadata>>() { bind(new TypeLiteral<Function<LoadBalancerInRegion, LoadBalancerMetadata>>() {
}).to(LoadBalancerToLoadBalancerMetadata.class); }).to(LoadBalancerToLoadBalancerMetadata.class);
} }

View File

@ -18,20 +18,17 @@
*/ */
package org.jclouds.elb.loadbalancer.functions; package org.jclouds.elb.loadbalancer.functions;
import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerType; import org.jclouds.loadbalancer.domain.LoadBalancerType;
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl; import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@ -45,50 +42,34 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class LoadBalancerToLoadBalancerMetadata implements Function<CrappyLoadBalancer, LoadBalancerMetadata> { public class LoadBalancerToLoadBalancerMetadata implements Function<LoadBalancerInRegion, LoadBalancerMetadata> {
@Resource
protected static Logger logger = Logger.NULL;
protected final Supplier<Set<? extends Location>> locations; protected final Supplier<Set<? extends Location>> locations;
protected final Supplier<Location> defaultLocationSupplier;
@Inject @Inject
public LoadBalancerToLoadBalancerMetadata(Supplier<Location> defaultLocationSupplier, public LoadBalancerToLoadBalancerMetadata(@Memoized Supplier<Set<? extends Location>> locations) {
@Memoized Supplier<Set<? extends Location>> locations) {
this.locations = locations; this.locations = locations;
this.defaultLocationSupplier = defaultLocationSupplier;
} }
@Override @Override
public LoadBalancerMetadata apply(CrappyLoadBalancer input) { public LoadBalancerMetadata apply(LoadBalancerInRegion input) {
Location location = input.getRegion() != null ? findLocationWithId(input.getRegion()) : defaultLocationSupplier Location location = findLocationWithId(input.getRegion());
.get();
String id = input.getRegion() != null ? input.getRegion() + "/" + input.getName() : input.getName(); return new LoadBalancerMetadataImpl(LoadBalancerType.LB, input.getName(), input.getName(), input.slashEncode(),
// TODO Builder location, null, ImmutableMap.<String, String> of(),
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, input.getName(), input.getName(), id, location, null, ImmutableSet.of(input.getLoadBalancer().getDnsName()));
ImmutableMap.<String, String> of(), ImmutableSet.of(input.getDnsName()));
} }
private Location findLocationWithId(final String locationId) { private Location findLocationWithId(final String locationId) {
if (locationId == null) return Iterables.find(locations.get(), new Predicate<Location>() {
return null;
try {
Location location = Iterables.find(locations.get(), new Predicate<Location>() {
@Override @Override
public boolean apply(Location input) { public boolean apply(Location input) {
return input.getId().equals(locationId); return input.getId().equals(locationId);
} }
}); });
return location;
} catch (NoSuchElementException e) {
logger.debug("couldn't match instance location %s in: %s", locationId, locations.get());
return null;
}
} }
} }

View File

@ -19,16 +19,14 @@
package org.jclouds.elb.loadbalancer.strategy; package org.jclouds.elb.loadbalancer.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.aws.util.AWSUtils.parseHandle; import static org.jclouds.aws.util.AWSUtils.parseHandle;
import java.util.NoSuchElementException;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.elb.ELBClient; import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy; import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
@ -42,10 +40,11 @@ import com.google.common.base.Function;
public class ELBGetLoadBalancerMetadataStrategy implements GetLoadBalancerMetadataStrategy { public class ELBGetLoadBalancerMetadataStrategy implements GetLoadBalancerMetadataStrategy {
private final ELBClient client; private final ELBClient client;
private final Function<CrappyLoadBalancer, LoadBalancerMetadata> converter; private final Function<LoadBalancerInRegion, LoadBalancerMetadata> converter;
@Inject @Inject
protected ELBGetLoadBalancerMetadataStrategy(ELBClient client, Function<CrappyLoadBalancer, LoadBalancerMetadata> converter) { protected ELBGetLoadBalancerMetadataStrategy(ELBClient client,
Function<LoadBalancerInRegion, LoadBalancerMetadata> converter) {
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.converter = checkNotNull(converter, "converter"); this.converter = checkNotNull(converter, "converter");
} }
@ -55,11 +54,8 @@ public class ELBGetLoadBalancerMetadataStrategy implements GetLoadBalancerMetada
String[] parts = parseHandle(id); String[] parts = parseHandle(id);
String region = parts[0]; String region = parts[0];
String name = parts[1]; String name = parts[1];
try { LoadBalancer input = client.getLoadBalancerClientForRegion(region).get(name);
return converter.apply(getOnlyElement(client.describeLoadBalancersInRegion(region, name))); return input != null ? converter.apply(new LoadBalancerInRegion(input, region)) : null;
} catch (NoSuchElementException e) {
return null;
}
} }
} }

View File

@ -33,9 +33,10 @@ import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.concurrent.Futures;
import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient; import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy; import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy;
@ -44,6 +45,7 @@ import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
/** /**
@ -56,17 +58,15 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy {
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER) @Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final ELBClient client;
private final ELBAsyncClient aclient; private final ELBAsyncClient aclient;
private final Function<CrappyLoadBalancer, LoadBalancerMetadata> converter; private final Function<LoadBalancerInRegion, LoadBalancerMetadata> converter;
private final ExecutorService executor; private final ExecutorService executor;
private final Supplier<Set<String>> regions; private final Supplier<Set<String>> regions;
@Inject @Inject
protected ELBListLoadBalancersStrategy(ELBClient client, ELBAsyncClient aclient, protected ELBListLoadBalancersStrategy(ELBAsyncClient aclient,
Function<CrappyLoadBalancer, LoadBalancerMetadata> converter, Function<LoadBalancerInRegion, LoadBalancerMetadata> converter,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Region Supplier<Set<String>> regions) { @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Region Supplier<Set<String>> regions) {
this.client = checkNotNull(client, "client");
this.aclient = checkNotNull(aclient, "aclient"); this.aclient = checkNotNull(aclient, "aclient");
this.regions = checkNotNull(regions, "regions"); this.regions = checkNotNull(regions, "regions");
this.converter = checkNotNull(converter, "converter"); this.converter = checkNotNull(converter, "converter");
@ -75,19 +75,32 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy {
@Override @Override
public Iterable<LoadBalancerMetadata> listLoadBalancers() { public Iterable<LoadBalancerMetadata> listLoadBalancers() {
Iterable<? extends CrappyLoadBalancer> loadBalancers;
Set<String> regions = this.regions.get();
if (regions.size() > 0)
loadBalancers = concat(transformParallel(regions, new Function<String, Future<? extends Set<? extends CrappyLoadBalancer>>>() {
@Override Iterable<LoadBalancerInRegion> loadBalancers = concat(transformParallel(regions.get(),
public ListenableFuture<Set<? extends CrappyLoadBalancer>> apply(String from) { new Function<String, Future<? extends Iterable<LoadBalancerInRegion>>>() {
return aclient.describeLoadBalancersInRegion(from);
}
}, executor, null, logger, "loadbalancers")); @Override
else public ListenableFuture<? extends Iterable<LoadBalancerInRegion>> apply(final String from) {
loadBalancers = client.describeLoadBalancersInRegion(null); // TODO: ELB.listLoadBalancers
return Futures.compose(aclient.getLoadBalancerClientForRegion(from).list(),
new Function<Iterable<LoadBalancer>, Iterable<LoadBalancerInRegion>>() {
@Override
public Iterable<LoadBalancerInRegion> apply(Iterable<LoadBalancer> input) {
return Iterables.transform(input,
new Function<LoadBalancer, LoadBalancerInRegion>() {
@Override
public LoadBalancerInRegion apply(LoadBalancer lb) {
return new LoadBalancerInRegion(lb, from);
}
});
}
}, executor);
}
}, executor, null, logger, "loadbalancers"));
return transform(loadBalancers, converter); return transform(loadBalancers, converter);
} }
} }

View File

@ -19,10 +19,12 @@
package org.jclouds.elb.loadbalancer.strategy; package org.jclouds.elb.loadbalancer.strategy;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Sets.filter;
import static org.jclouds.aws.util.AWSUtils.getRegionFromLocationOrNull; import static org.jclouds.aws.util.AWSUtils.getRegionFromLocationOrNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -33,15 +35,14 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.elb.ELBClient; import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy; import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
/** /**
* *
@ -53,33 +54,40 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER) @Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final ELBClient client; protected final ELBClient client;
protected final Function<CrappyLoadBalancer, LoadBalancerMetadata> converter; protected final Function<LoadBalancerInRegion, LoadBalancerMetadata> converter;
@Inject @Inject
protected ELBLoadBalanceNodesStrategy(ELBClient client, Function<CrappyLoadBalancer, LoadBalancerMetadata> converter) { protected ELBLoadBalanceNodesStrategy(ELBClient client,
Function<LoadBalancerInRegion, LoadBalancerMetadata> converter) {
this.client = checkNotNull(client, "client"); this.client = checkNotNull(client, "client");
this.converter = checkNotNull(converter, "converter"); this.converter = checkNotNull(converter, "converter");
} }
@Override @Override
public LoadBalancerMetadata createLoadBalancerInLocation(Location location, String name, String protocol, public LoadBalancerMetadata createLoadBalancerInLocation(Location location, String name, String protocol,
int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) { int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) {
checkNotNull(location, "location"); checkNotNull(location, "location");
String region = getRegionFromLocationOrNull(location); String region = getRegionFromLocationOrNull(location);
List<String> availabilityZones = Lists.newArrayList(Iterables.transform(nodes, Set<String> availabilityZones = ImmutableSet.copyOf(transform(nodes, new Function<NodeMetadata, String>() {
new Function<NodeMetadata, String>() {
@Override @Override
public String apply(NodeMetadata from) { public String apply(NodeMetadata from) {
return from.getLocation().getId(); return from.getLocation().getId();
} }
})); }));
client.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort, logger.debug(">> creating loadBalancer(%s)", name);
availabilityZones.toArray(new String[] {})); try {
String dnsName = client.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort,
availabilityZones.toArray(new String[] {}));
logger.debug("<< created loadBalancer(%s) dnsName(%s)", name, dnsName);
} catch (IllegalStateException e) {
logger.debug("<< reusing loadBalancer(%s)", name);
// TODO: converge availability zones
}
List<String> instanceIds = Lists.newArrayList(Iterables.transform(nodes, new Function<NodeMetadata, String>() { Set<String> instanceIds = ImmutableSet.copyOf(transform(nodes, new Function<NodeMetadata, String>() {
@Override @Override
public String apply(NodeMetadata from) { public String apply(NodeMetadata from) {
@ -87,22 +95,17 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
} }
})); }));
String[] instanceIdArray = instanceIds.toArray(new String[] {}); logger.debug(">> converging loadBalancer(%s) to instances(%s)", name, instanceIds);
Set<String> registeredInstanceIds = client.getInstanceClientForRegion(region).registerInstancesWithLoadBalancer(
instanceIds, name);
Set<String> registeredInstanceIds = client.registerInstancesWithLoadBalancerInRegion(region, name, Set<String> instancesToRemove = filter(registeredInstanceIds, not(in(instanceIds)));
instanceIdArray); if (instancesToRemove.size() > 0) {
logger.debug(">> deregistering instances(%s) from loadBalancer(%s)", instancesToRemove, name);
// deregister instances client.getInstanceClientForRegion(region).deregisterInstancesFromLoadBalancer(instancesToRemove, name);
boolean changed = registeredInstanceIds.removeAll(instanceIds);
if (changed) {
List<String> list = new ArrayList<String>(registeredInstanceIds);
instanceIdArray = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
instanceIdArray[i] = list.get(i);
}
if (instanceIdArray.length > 0)
client.deregisterInstancesWithLoadBalancerInRegion(region, name, instanceIdArray);
} }
return converter.apply(Iterables.getOnlyElement(client.describeLoadBalancersInRegion(region, name))); logger.debug("<< converged loadBalancer(%s) ", name);
return converter.apply(new LoadBalancerInRegion(client.getLoadBalancerClientForRegion(region).get(name), region));
} }
} }

View File

@ -0,0 +1,118 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Set;
import org.jclouds.elb.domain.InstanceState;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.inject.Inject;
/**
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference/API_DescribeInstanceHealth.html"
* >docs</a>
*
* @author Adrian Cole
*/
public class DescribeInstanceHealthResultHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<Set<InstanceState>> {
private final InstanceStateHandler instanceStateHandler;
private StringBuilder currentText = new StringBuilder();
private Builder<InstanceState> instanceStates = ImmutableSet.<InstanceState> builder();
private boolean inStates;
protected int memberDepth;
@Inject
public DescribeInstanceHealthResultHandler(InstanceStateHandler instanceStateHandler) {
this.instanceStateHandler = instanceStateHandler;
}
/**
* {@inheritDoc}
*/
@Override
public Set<InstanceState> getResult() {
return instanceStates.build();
}
/**
* {@inheritDoc}
*/
@Override
public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException {
if (equalsOrSuffix(qName, "member")) {
memberDepth++;
} else if (equalsOrSuffix(qName, "InstanceStates")) {
inStates = true;
}
if (inStates) {
instanceStateHandler.startElement(url, name, qName, attributes);
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (equalsOrSuffix(qName, "member")) {
endMember(uri, name, qName);
memberDepth--;
} else if (equalsOrSuffix(qName, "InstanceStates")) {
inStates = false;
} else if (inStates) {
instanceStateHandler.endElement(uri, name, qName);
}
currentText = new StringBuilder();
}
protected void endMember(String uri, String name, String qName) throws SAXException {
if (inStates) {
if (memberDepth == 1)
instanceStates.add(instanceStateHandler.getResult());
else
instanceStateHandler.endElement(uri, name, qName);
}
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
if (inStates) {
instanceStateHandler.characters(ch, start, length);
} else {
currentText.append(ch, start, length);
}
}
}

View File

@ -1,195 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.xml;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.elb.domain.CrappyLoadBalancer;
import org.jclouds.elb.domain.CrappyLoadBalancer.AppCookieStickinessPolicy;
import org.jclouds.elb.domain.CrappyLoadBalancer.LBCookieStickinessPolicy;
import org.jclouds.elb.domain.CrappyLoadBalancer.LoadBalancerListener;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import org.xml.sax.Attributes;
import com.google.common.collect.Sets;
/**
*
* @author Lili Nadar
*/
public class DescribeLoadBalancersResponseHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<Set<CrappyLoadBalancer>> {
private final DateService dateService;
private final LoadBalancerListenerHandler listenerHandler;
@Inject
public DescribeLoadBalancersResponseHandler(DateService dateService, LoadBalancerListenerHandler listenerHandler) {
this.dateService = dateService;
this.listenerHandler = listenerHandler;
}
@Resource
protected Logger logger = Logger.NULL;
private Set<CrappyLoadBalancer> contents = Sets.newLinkedHashSet();
private StringBuilder currentText = new StringBuilder();
private boolean inListenerDescriptions = false;
private boolean inInstances = false;
private boolean inAppCookieStickinessPolicies = false;
private boolean inLBCookieStickinessPolicies = false;
private boolean inAvailabilityZones = false;
// TODO unused?
private boolean inLoadBalancerDescriptions = false;
private CrappyLoadBalancer elb;
// TODO unused?
private AppCookieStickinessPolicy appCookieStickinessPolicy;
// TODO unused?
private LBCookieStickinessPolicy lBCookieStickinessPolicy;
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equals("ListenerDescriptions") || inListenerDescriptions) {
inListenerDescriptions = true;
} else if (qName.equals("AppCookieStickinessPolicies")) {
inAppCookieStickinessPolicies = true;
} else if (qName.equals("LBCookieStickinessPolicies")) {
inLBCookieStickinessPolicies = true;
} else if (qName.equals("LoadBalancerDescriptions")) {
inLoadBalancerDescriptions = true;
} else if (qName.equals("Instances")) {
inInstances = true;
} else if (qName.equals("AvailabilityZones")) {
inAvailabilityZones = true;
}
if (qName.equals("member")) {
if (!(inListenerDescriptions || inAppCookieStickinessPolicies || inInstances || inLBCookieStickinessPolicies || inAvailabilityZones)) {
elb = new CrappyLoadBalancer();
}
}
}
public void endElement(String uri, String localName, String qName) {
// if end tag is one of below then set inXYZ to false
if (qName.equals("ListenerDescriptions")) {
inListenerDescriptions = false;
} else if (qName.equals("AppCookieStickinessPolicies")) {
inAppCookieStickinessPolicies = false;
} else if (qName.equals("LBCookieStickinessPolicies")) {
inLBCookieStickinessPolicies = false;
} else if (qName.equals("LoadBalancerDescriptions")) {
inLoadBalancerDescriptions = false;
} else if (qName.equals("Instances")) {
inInstances = false;
} else if (qName.equals("AvailabilityZones")) {
inAvailabilityZones = false;
}
if (qName.equals("DNSName")) {
elb.setDnsName(currentText.toString().trim());
} else if (qName.equals("LoadBalancerName")) {
elb.setName(currentText.toString().trim());
} else if (qName.equals("InstanceId")) {
elb.getInstanceIds().add(currentText.toString().trim());
}
else if (qName.equals("member")) {
if (inAvailabilityZones) {
elb.getAvailabilityZones().add(currentText.toString().trim());
} else if (!(inListenerDescriptions || inAppCookieStickinessPolicies || inInstances
|| inLBCookieStickinessPolicies || inAvailabilityZones)) {
try {
String region = AWSUtils.findRegionInArgsOrNull(getRequest());
elb.setRegion(region);
contents.add(elb);
} catch (NullPointerException e) {
logger.warn(e, "malformed load balancer: %s", localName);
this.elb = null;
}
}
}
currentText = new StringBuilder();
}
@Override
public Set<CrappyLoadBalancer> getResult() {
return contents;
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
@Override
public DescribeLoadBalancersResponseHandler setContext(HttpRequest request) {
listenerHandler.setContext(request);
super.setContext(request);
return this;
}
public static class LoadBalancerListenerHandler extends ParseSax.HandlerWithResult<Set<LoadBalancerListener>> {
private Set<LoadBalancerListener> listeners = Sets.newHashSet();
private StringBuilder currentText = new StringBuilder();
private LoadBalancerListener listener;
public void startElement(String uri, String name, String qName, Attributes attrs) {
if (qName.equals("member")) {
listener = new LoadBalancerListener();
}
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("Protocol")) {
listener.setProtocol(currentText.toString().trim());
} else if (qName.equals("LoadBalancerPort")) {
listener.setLoadBalancerPort(Integer.parseInt(currentText.toString().trim()));
} else if (qName.equals("InstancePort")) {
listener.setInstancePort(Integer.parseInt(currentText.toString().trim()));
} else if (qName.equals("member")) {
listeners.add(listener);
}
currentText = new StringBuilder();
}
@Override
public Set<LoadBalancerListener> getResult() {
return listeners;
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.xml;
import static org.jclouds.util.SaxUtils.currentOrNull;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import org.jclouds.elb.domain.InstanceState;
import org.jclouds.http.functions.ParseSax;
import org.xml.sax.SAXException;
/**
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference/API_InstanceState.html"
* >xml</a>
*
* @author Adrian Cole
*/
public class InstanceStateHandler extends ParseSax.HandlerForGeneratedRequestWithResult<InstanceState> {
private StringBuilder currentText = new StringBuilder();
private InstanceState.Builder builder = InstanceState.builder();
/**
* {@inheritDoc}
*/
@Override
public InstanceState getResult() {
try {
return builder.build();
} finally {
builder = InstanceState.builder();
}
}
/**
* {@inheritDoc}
*/
@Override
public void endElement(String uri, String name, String qName) throws SAXException {
if (equalsOrSuffix(qName, "Description")) {
builder.description(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "InstanceId")) {
builder.instanceId(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "ReasonCode")) {
builder.reasonCode(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "State")) {
builder.state(currentOrNull(currentText));
}
currentText = new StringBuilder();
}
/**
* {@inheritDoc}
*/
@Override
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -20,21 +20,11 @@ package org.jclouds.elb.xml;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
public class RegisterInstancesWithLoadBalancerResponseHandler extends ParseSax.HandlerWithResult<Set<String>> { public class InstancesResultHandler extends ParseSax.HandlerWithResult<Set<String>> {
@Inject
public RegisterInstancesWithLoadBalancerResponseHandler() {
}
@Resource
protected Logger logger = Logger.NULL;
private Set<String> instanceIds = Sets.newLinkedHashSet(); private Set<String> instanceIds = Sets.newLinkedHashSet();
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
@ -42,7 +32,6 @@ public class RegisterInstancesWithLoadBalancerResponseHandler extends ParseSax.H
public void endElement(String uri, String localName, String qName) { public void endElement(String uri, String localName, String qName) {
if (qName.equals("InstanceId")) if (qName.equals("InstanceId"))
instanceIds.add(currentText.toString().trim()); instanceIds.add(currentText.toString().trim());
currentText = new StringBuilder(); currentText = new StringBuilder();
} }

View File

@ -53,6 +53,7 @@ public class LoadBalancerHandler extends ParseSax.HandlerForGeneratedRequestWith
private boolean inHealthCheck; private boolean inHealthCheck;
private boolean inListeners; private boolean inListeners;
private boolean inAvailabilityZones;
protected int memberDepth; protected int memberDepth;
@ -79,7 +80,10 @@ public class LoadBalancerHandler extends ParseSax.HandlerForGeneratedRequestWith
inHealthCheck = true; inHealthCheck = true;
} else if (equalsOrSuffix(qName, "ListenerDescriptions")) { } else if (equalsOrSuffix(qName, "ListenerDescriptions")) {
inListeners = true; inListeners = true;
} else if (equalsOrSuffix(qName, "AvailabilityZones")) {
inAvailabilityZones = true;
} }
if (inListeners) { if (inListeners) {
listenerHandler.startElement(url, name, qName, attributes); listenerHandler.startElement(url, name, qName, attributes);
} }
@ -95,6 +99,8 @@ public class LoadBalancerHandler extends ParseSax.HandlerForGeneratedRequestWith
memberDepth--; memberDepth--;
} else if (equalsOrSuffix(qName, "ListenerDescriptions")) { } else if (equalsOrSuffix(qName, "ListenerDescriptions")) {
inListeners = false; inListeners = false;
} else if (equalsOrSuffix(qName, "AvailabilityZones")) {
inAvailabilityZones = false;
} else if (equalsOrSuffix(qName, "HealthCheck")) { } else if (equalsOrSuffix(qName, "HealthCheck")) {
builder.healthCheck(healthCheckHandler.getResult()); builder.healthCheck(healthCheckHandler.getResult());
inHealthCheck = false; inHealthCheck = false;
@ -121,6 +127,8 @@ public class LoadBalancerHandler extends ParseSax.HandlerForGeneratedRequestWith
protected void endMember(String uri, String name, String qName) throws SAXException { protected void endMember(String uri, String name, String qName) throws SAXException {
if (inListeners) { if (inListeners) {
builder.listener(listenerHandler.getResult()); builder.listener(listenerHandler.getResult());
} else if (inAvailabilityZones) {
builder.availabilityZone(currentOrNull(currentText));
} }
} }

View File

@ -1,183 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.date.DateService;
import org.jclouds.elb.config.ELBRestClientModule;
import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.elb.xml.DescribeLoadBalancersResponseHandler;
import org.jclouds.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.BaseAsyncClientTest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code ELBAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "ELBAsyncClientTest")
public class ELBAsyncClientTest extends BaseAsyncClientTest<ELBAsyncClient> {
public void testCreateLoadBalancerInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("createLoadBalancerInRegion", String.class, String.class,
String.class, int.class, int.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "name", "http", 80, 80);
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Action=CreateLoadBalancer&Listeners.member.1.Protocol=http&LoadBalancerName=name&Listeners.member.1.LoadBalancerPort=80&Listeners.member.1.InstancePort=80",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, CreateLoadBalancerResponseHandler.class);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(request);
}
public void testDescribeLoadBalancers() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("describeLoadBalancersInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Action=DescribeLoadBalancers",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeLoadBalancersResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testDescribeLoadBalancersArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("describeLoadBalancersInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Action=DescribeLoadBalancers&LoadBalancerNames.member.1=1&LoadBalancerNames.member.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeLoadBalancersResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testRegisterInstancesWithLoadBalancer() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("registerInstancesWithLoadBalancerInRegion", String.class,
String.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "ReferenceAP1", "i-6055fa09");
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Action=RegisterInstancesWithLoadBalancer&LoadBalancerName=ReferenceAP1&Instances.member.1.InstanceId=i-6055fa09",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, RegisterInstancesWithLoadBalancerResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDeregisterInstancesWithLoadBalancer() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("deregisterInstancesWithLoadBalancerInRegion", String.class,
String.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "ReferenceAP1", "i-6055fa09");
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Action=DeregisterInstancesFromLoadBalancer&LoadBalancerName=ReferenceAP1&Instances.member.1.InstanceId=i-6055fa09",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<ELBAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ELBAsyncClient>>() {
};
}
@ConfiguresRestClient
private static final class TestELBRestClientModule extends ELBRestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(final DateService dateService) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestELBRestClientModule();
}
@Override
public ApiMetadata createApiMetadata() {
return new ELBApiMetadata();
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), FormSigner.class);
}
}

View File

@ -1,107 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull;
import java.util.Set;
import org.jclouds.apis.BaseContextLiveTest;
import org.jclouds.elb.domain.CrappyLoadBalancer;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.reflect.TypeParameter;
import com.google.common.reflect.TypeToken;
/**
* Tests behavior of {@code ELBClient}
*
* @author Lili Nader
*/
@Test(groups = "live", singleThreaded = true, testName = "ELBClientLiveTest")
public class ELBClientLiveTest<S extends ELBClient, A extends ELBAsyncClient> extends BaseContextLiveTest<RestContext<S, A>> {
public ELBClientLiveTest() {
provider = "elb";
}
protected S client;
protected String name = "TestLoadBalancer";
@Override
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
client = context.getApi();
}
@Test
public void testCreateLoadBalancer() {
createLoadBalancerInRegionZone(null, checkNotNull(System.getProperty("test." + provider + ".zone"), "test."
+ provider + ".zone"), name);
}
protected void createLoadBalancerInRegionZone(String region, String zone, String name) {
String dnsName = client.createLoadBalancerInRegion(region, name, "http", 80, 80, zone);
assertNotNull(dnsName);
assert (dnsName.startsWith(name));
}
@Test(dependsOnMethods = "testCreateLoadBalancer")
public void testDescribeLoadBalancers() {
describeLoadBalancerInRegion(null);
}
protected void describeLoadBalancerInRegion(String region) {
Set<? extends CrappyLoadBalancer> allResults = client.describeLoadBalancersInRegion(region);
assertNotNull(allResults);
assert (allResults.size() >= 1) : region;
}
@Test(dependsOnMethods = "testDescribeLoadBalancers")
public void testDeleteLoadBalancer() {
deleteLoadBalancerInRegion(null);
}
protected void deleteLoadBalancerInRegion(String region) {
client.deleteLoadBalancerInRegion(region, name);
}
@AfterClass(groups = { "integration", "live" })
protected void tearDownContext() {
try {
testDeleteLoadBalancer();
} finally {
super.tearDownContext();
}
}
@SuppressWarnings({ "serial", "unchecked" })
@Override
protected TypeToken<RestContext<S, A>> contextType() {
return new TypeToken<RestContext<S, A>>() {
}.where(new TypeParameter<S>() {
}, (TypeToken) TypeToken.of(ELBClient.class)).where(new TypeParameter<A>() {
}, (TypeToken) TypeToken.of(ELBAsyncClient.class));
}
}

View File

@ -0,0 +1,69 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.features;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import org.jclouds.elb.domain.InstanceState;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.internal.BaseELBClientLiveTest;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Test(groups = "live", testName = "InstanceClientLiveTest")
public class InstanceClientLiveTest extends BaseELBClientLiveTest {
private void checkInstanceState(InstanceState instanceState) {
checkNotNull(instanceState.getDescription(), "Description cannot be null for InstanceState");
checkNotNull(instanceState.getInstanceId(), "InstanceId cannot be null for InstanceState");
checkNotNull(instanceState.getReasonCode(),
"While ReasonCode can be null for InstanceState, its Optional wrapper cannot");
checkNotNull(instanceState.getState(), "State cannot be null for InstanceState");
}
@Test
protected void testListInstanceStates() {
for (LoadBalancer loadBalancer : context.getApi().getLoadBalancerClientForRegion(null).list()) {
Set<InstanceState> response = client().listInstanceStatesOfLoadBalancer(loadBalancer.getName());
for (InstanceState instanceState : response) {
checkInstanceState(instanceState);
}
if (response.size() > 0) {
InstanceState instanceState = response.iterator().next();
Assert.assertEquals(
client().listInstanceStatesOfLoadBalancer(ImmutableSet.of(instanceState.getInstanceId()),
loadBalancer.getName()), instanceState);
}
}
}
protected InstanceClient client() {
return context.getApi().getInstanceClientForRegion(null);
}
}

View File

@ -19,30 +19,28 @@
package org.jclouds.elb.loadbalancer; package org.jclouds.elb.loadbalancer;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.util.HashSet;
import java.util.Set;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient; import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.BaseLoadBalancerServiceLiveTest; import org.jclouds.loadbalancer.BaseLoadBalancerServiceLiveTest;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.sshj.config.SshjSshClientModule; import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/** /**
* *
* @author Lili Nadar * @author Lili Nadar
*/ */
@Test(groups = "live", singleThreaded = true, testName = "ELBLoadBalancerServiceLiveTest") @Test(groups = "live", singleThreaded = true, testName = "ELBLoadBalancerServiceLiveTest")
public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest { public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest {
public ELBLoadBalancerServiceLiveTest() { public ELBLoadBalancerServiceLiveTest() {
provider = "elb"; provider = "elb";
computeProvider = "ec2";
} }
@Override @Override
@ -52,22 +50,21 @@ public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT
@Override @Override
protected void validateNodesInLoadBalancer() { protected void validateNodesInLoadBalancer() {
RestContext<ELBClient, ELBAsyncClient> elbContext = context.unwrap(); RestContext<ELBClient, ELBAsyncClient> elbContext = view.unwrap();
// TODO create a LoadBalancer object and an appropriate list method so that this // TODO create a LoadBalancer object and an appropriate list method so that this
// does not have to be EC2 specific code // does not have to be EC2 specific code
ELBClient elbClient = elbContext.getApi(); ELBClient elbClient = elbContext.getApi();
Set<String> instanceIds = new HashSet<String>(); Builder<String> instanceIds = ImmutableSet.<String> builder();
for (NodeMetadata node : nodes) { for (NodeMetadata node : nodes) {
instanceIds.add(node.getProviderId()); instanceIds.add(node.getProviderId());
} }
Set<? extends CrappyLoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(null);
assertNotNull(elbs); PaginatedSet<LoadBalancer> elbs = elbClient.getLoadBalancerClientForRegion(null).list();
for (CrappyLoadBalancer elb : elbs) { for (LoadBalancer elb : elbs) {
if (elb.getName().equals(group)) if (elb.getName().equals(group))
assertEquals(elb.getInstanceIds(), instanceIds); assertEquals(elb.getInstanceIds(), instanceIds.build());
} }
} }
} }

View File

@ -68,6 +68,7 @@ public class DescribeLoadBalancersResponseTest extends BaseHandlerTest {
.instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632")) .instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632"))
.listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build()) .listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build())
.listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build()) .listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build())
.availabilityZone("us-east-1a")
.build())); .build()));
} }

View File

@ -70,6 +70,7 @@ public class GetLoadBalancerResponseTest extends BaseHandlerTest {
.instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632")) .instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632"))
.listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build()) .listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build())
.listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build()) .listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build())
.availabilityZone("us-east-1a")
.build(); .build();
} }
} }

View File

@ -16,44 +16,39 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.elb.xml; package org.jclouds.elb.parse;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.InputStream; import java.io.InputStream;
import java.util.Set; import java.util.Set;
import org.jclouds.elb.xml.InstancesResultHandler;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Sets; import com.google.common.collect.ImmutableSet;
/** /**
* Tests behavior of {@code RegisterInstancesWithLoadBalancerResponseHandler}
*
* @author Adrian Cole * @author Adrian Cole
*/ */
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "RegisterInstancesWithLoadBalancerResponseHandlerTest") @Test(groups = "unit", testName = "InstancesResultHandlerTest")
public class RegisterInstancesWithLoadBalancerResponseHandlerTest extends BaseHandlerTest { public class InstancesResultHandlerTest extends BaseHandlerTest {
public void testParse() { public void test() {
InputStream is = getClass().getResourceAsStream("/register_instances_with_loadbalancer.xml"); InputStream is = getClass().getResourceAsStream("/instances.xml");
Set<String> instanceIds = Sets.newHashSet(); Set<String> expected = expected();
instanceIds.add("i-6055fa09");
instanceIds.add("i-9055fa55");
Set<String> result = parseXML(is); InstancesResultHandler handler = injector.getInstance(InstancesResultHandler.class);
assertEquals(result, instanceIds);
}
private Set<String> parseXML(InputStream is) {
RegisterInstancesWithLoadBalancerResponseHandler handler = injector
.getInstance(RegisterInstancesWithLoadBalancerResponseHandler.class);
Set<String> result = factory.create(handler).parse(is); Set<String> result = factory.create(handler).parse(is);
return result;
assertEquals(result.toString(), expected.toString());
} }
public Set<String> expected() {
return ImmutableSet.of("i-6055fa09", "i-9055fa55");
}
} }

View File

@ -1,75 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.xml;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.elb.domain.CrappyLoadBalancer;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
/**
* Tests behavior of {@code DescribeLoadBalancerResponseHandler}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "DescribeLoadBalancerResponseHandlerTest")
public class DescribeLoadBalancerResponseHandlerTest extends BaseHandlerTest {
public void testParse() {
InputStream is = getClass().getResourceAsStream("/describe_loadbalancers.xml");
Set<CrappyLoadBalancer> contents = Sets.newHashSet();
CrappyLoadBalancer dummy = new CrappyLoadBalancer(null, "my-load-balancer", ImmutableSet.of("i-5b33e630",
"i-8f26d7e4", "i-5933e632"), ImmutableSet.of("us-east-1a"),
"my-load-balancer-1400212309.us-east-1.elb.amazonaws.com");
contents.add(dummy);
Set<CrappyLoadBalancer> result = parseLoadBalancers(is);
assertEquals(result, contents);
}
private Set<CrappyLoadBalancer> parseLoadBalancers(InputStream is) {
DescribeLoadBalancersResponseHandler handler = injector.getInstance(DescribeLoadBalancersResponseHandler.class);
addDefaultRegionToHandler(handler);
Set<CrappyLoadBalancer> result = factory.create(handler).parse(is);
return result;
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(ImmutableList.<Object> of());
replay(request);
handler.setContext(request);
}
}

View File

@ -16,6 +16,14 @@
</encoder> </encoder>
</appender> </appender>
<appender name="LBFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-loadbalancer.log</file>
<encoder>
<Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
</encoder>
</appender>
<appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender"> <appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
<file>target/test-data/jclouds-compute.log</file> <file>target/test-data/jclouds-compute.log</file>
@ -56,6 +64,11 @@
<appender-ref ref="COMPUTEFILE" /> <appender-ref ref="COMPUTEFILE" />
</logger> </logger>
<logger name="jclouds.loadbalancer">
<level value="DEBUG" />
<appender-ref ref="LBFILE" />
</logger>
<logger name="jclouds.ssh"> <logger name="jclouds.ssh">
<level value="DEBUG" /> <level value="DEBUG" />
<appender-ref ref="SSHFILE" /> <appender-ref ref="SSHFILE" />

View File

@ -21,12 +21,9 @@ package org.jclouds.loadbalancer;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.ContextBuilder; import org.jclouds.ContextBuilder;
@ -34,15 +31,15 @@ import org.jclouds.apis.BaseViewLiveTest;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException; import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.TemplateBuilderSpec;
import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.domain.LoginCredentials.Builder; import org.jclouds.domain.LoginCredentials.Builder;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.SshClient; import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -60,12 +57,10 @@ import com.google.inject.Module;
@Test(groups = "live", singleThreaded = true) @Test(groups = "live", singleThreaded = true)
public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<LoadBalancerServiceContext> { public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<LoadBalancerServiceContext> {
protected String imageId; protected TemplateBuilderSpec template;
protected String loginUser;
protected String authenticateSudo;
protected LoginCredentials loginCredentials = LoginCredentials.builder().user("root").build(); protected LoginCredentials loginCredentials = LoginCredentials.builder().user("root").build();
protected Properties setupComputeProperties() { protected Properties setupComputeProperties() {
Properties overrides = new Properties(); Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
@ -75,34 +70,29 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<L
computeEndpoint = setIfTestSystemPropertyPresent(overrides, provider + ".compute.endpoint"); computeEndpoint = setIfTestSystemPropertyPresent(overrides, provider + ".compute.endpoint");
computeApiversion = setIfTestSystemPropertyPresent(overrides, provider + ".compute.api-version"); computeApiversion = setIfTestSystemPropertyPresent(overrides, provider + ".compute.api-version");
computeBuildversion = setIfTestSystemPropertyPresent(overrides, provider + ".compute.build-version"); computeBuildversion = setIfTestSystemPropertyPresent(overrides, provider + ".compute.build-version");
imageId = setIfTestSystemPropertyPresent(overrides, provider + ".compute.image-id"); String spec = setIfTestSystemPropertyPresent(overrides, provider + ".compute.template");
loginUser = setIfTestSystemPropertyPresent(overrides, provider + ".compute.image.login-user"); if (spec != null) {
authenticateSudo = setIfTestSystemPropertyPresent(overrides, provider + ".compute.image.authenticate-sudo"); template = TemplateBuilderSpec.parse(spec);
if (template.getLoginUser() != null) {
if (loginUser != null) { Iterable<String> userPass = Splitter.on(':').split(template.getLoginUser());
Iterable<String> userPass = Splitter.on(':').split(loginUser); Builder loginCredentialsBuilder = LoginCredentials.builder();
Builder loginCredentialsBuilder = LoginCredentials.builder(); loginCredentialsBuilder.user(Iterables.get(userPass, 0));
loginCredentialsBuilder.user(Iterables.get(userPass, 0)); if (Iterables.size(userPass) == 2)
if (Iterables.size(userPass) == 2) loginCredentialsBuilder.password(Iterables.get(userPass, 1));
loginCredentialsBuilder.password(Iterables.get(userPass, 1)); if (template.getAuthenticateSudo() != null)
if (authenticateSudo != null) loginCredentialsBuilder.authenticateSudo(template.getAuthenticateSudo());
loginCredentialsBuilder.authenticateSudo(Boolean.valueOf(authenticateSudo)); loginCredentials = loginCredentialsBuilder.build();
loginCredentials = loginCredentialsBuilder.build(); }
} }
return overrides; return overrides;
} }
protected SshClient.Factory sshFactory;
protected String group; protected String group;
protected RetryablePredicate<HostAndPort> socketTester; protected RetryablePredicate<HostAndPort> socketTester;
protected Set<? extends NodeMetadata> nodes; protected Set<? extends NodeMetadata> nodes;
protected Template template;
protected Map<String, String> keyPair;
protected LoadBalancerMetadata loadbalancer; protected LoadBalancerMetadata loadbalancer;
protected LoadBalancerServiceContext context;
protected String computeProvider; protected String computeProvider;
protected String computeIdentity; protected String computeIdentity;
protected String computeCredential; protected String computeCredential;
@ -114,27 +104,29 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<L
@BeforeClass(groups = { "integration", "live" }) @BeforeClass(groups = { "integration", "live" })
@Override @Override
public void setupContext() { public void setupContext() {
setServiceDefaults(); super.setupContext();
if (group == null) if (group == null)
group = checkNotNull(provider, "provider"); group = checkNotNull(provider, "provider");
// groups need to work with hyphens in them, so let's make sure there is // groups need to work with hyphens in them, so let's make sure there is
// one! // one, without making it the first or last character
if (group.indexOf('-') == -1) if (group.indexOf('-') == -1)
group = group + "-"; group = new StringBuilder(group).insert(1, "-").toString();
super.setupContext();
initializeComputeContext(); initializeComputeContext();
buildSocketTester(); buildSocketTester();
} }
public void setServiceDefaults() {
}
protected void initializeComputeContext() { protected void initializeComputeContext() {
if (computeContext != null) if (computeContext != null)
computeContext.close(); computeContext.close();
computeContext = ContextBuilder.newBuilder(computeProvider).modules(setupModules()).overrides( Properties overrides = setupComputeProperties();
setupComputeProperties()).build(ComputeServiceContext.class); ContextBuilder builder = ContextBuilder.newBuilder(computeProvider)
.credentials(computeIdentity, computeCredential).overrides(overrides).modules(setupModules());
if (computeApiversion != null)
builder.apiVersion(computeApiversion);
if (computeBuildversion != null)
builder.buildVersion(computeBuildversion);
computeContext = builder.buildView(ComputeServiceContext.class);
} }
protected void buildSocketTester() { protected void buildSocketTester() {
@ -147,7 +139,10 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<L
@BeforeClass(groups = { "integration", "live" }, dependsOnMethods = "setupContext") @BeforeClass(groups = { "integration", "live" }, dependsOnMethods = "setupContext")
public void createNodes() throws RunNodesException { public void createNodes() throws RunNodesException {
try { try {
nodes = computeContext.getComputeService().createNodesInGroup(group, 2); TemplateBuilder builder = computeContext.getComputeService().templateBuilder();
if (template != null)
builder.from(template);
nodes = computeContext.getComputeService().createNodesInGroup(group, 2, builder.build());
} catch (RunNodesException e) { } catch (RunNodesException e) {
nodes = e.getSuccessfulNodes(); nodes = e.getSuccessfulNodes();
throw e; throw e;
@ -158,7 +153,7 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<L
public void testLoadBalanceNodesMatching() throws Exception { public void testLoadBalanceNodesMatching() throws Exception {
// create load balancers // create load balancers
loadbalancer = context.getLoadBalancerService().createLoadBalancerInLocation(null, group, "HTTP", 80, 80, nodes); loadbalancer = view.getLoadBalancerService().createLoadBalancerInLocation(null, group, "HTTP", 80, 80, nodes);
assertNotNull(loadbalancer); assertNotNull(loadbalancer);
validateNodesInLoadBalancer(); validateNodesInLoadBalancer();
@ -169,21 +164,22 @@ public abstract class BaseLoadBalancerServiceLiveTest extends BaseViewLiveTest<L
@Test(enabled = true, dependsOnMethods = "testLoadBalanceNodesMatching") @Test(enabled = true, dependsOnMethods = "testLoadBalanceNodesMatching")
public void testDestroyLoadBalancers() throws Exception { public void testDestroyLoadBalancers() throws Exception {
context.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId()); view.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId());
} }
@AfterTest @AfterClass(groups = { "integration", "live" })
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException { @Override
protected void tearDownContext() {
if (loadbalancer != null) { if (loadbalancer != null) {
context.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId()); view.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId());
} }
if (nodes != null) { if (nodes != null) {
computeContext.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); computeContext.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group));
} }
computeContext.close(); computeContext.close();
context.close(); super.tearDownContext();
} }
@Override @Override
protected TypeToken<LoadBalancerServiceContext> viewType() { protected TypeToken<LoadBalancerServiceContext> viewType() {
return TypeToken.of(LoadBalancerServiceContext.class); return TypeToken.of(LoadBalancerServiceContext.class);