refactored common location logic in aws and moved elb to its own module

This commit is contained in:
Adrian Cole 2011-01-03 20:20:42 +01:00
parent c9d1ef6d11
commit ada49c2b3b
84 changed files with 2076 additions and 682 deletions

View File

@ -35,7 +35,7 @@
<properties> <properties>
<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.apiversion>2009-11-25</test.elb.apiversion> <test.elb.apiversion>2010-07-01</test.elb.apiversion>
<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>
</properties> </properties>
@ -60,6 +60,12 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-jsch</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-loadbalancer</artifactId> <artifactId>jclouds-loadbalancer</artifactId>

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb; package org.jclouds.elb;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION; import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION; import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
@ -29,20 +29,23 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import org.jclouds.aws.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.aws.elb.binders.BindELBInstanceIdsToIndexedFormParams;
import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.aws.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.aws.elb.xml.DescribeLoadBalancersResponseHandler;
import org.jclouds.aws.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.elb.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.elb.binders.BindLoadBalancerNamesToIndexedFormParams;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.elb.xml.DescribeLoadBalancersResponseHandler;
import org.jclouds.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
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.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.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -56,7 +59,7 @@ import com.google.common.util.concurrent.ListenableFuture;
@FormParams(keys = VERSION, values = ELBAsyncClient.VERSION) @FormParams(keys = VERSION, values = ELBAsyncClient.VERSION)
@VirtualHost @VirtualHost
public interface ELBAsyncClient { public interface ELBAsyncClient {
public static final String VERSION = "2009-11-25"; public static final String VERSION = "2010-07-01";
/** /**
* @see ELBClient#createLoadBalancerInRegion * @see ELBClient#createLoadBalancerInRegion
@ -67,8 +70,7 @@ public interface ELBAsyncClient {
@FormParams(keys = ACTION, values = "CreateLoadBalancer") @FormParams(keys = ACTION, values = "CreateLoadBalancer")
ListenableFuture<String> createLoadBalancerInRegion( ListenableFuture<String> createLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name, @FormParam("LoadBalancerName") String name, @FormParam("Listeners.member.1.Protocol") String protocol,
@FormParam("Listeners.member.1.Protocol") String protocol,
@FormParam("Listeners.member.1.LoadBalancerPort") int loadBalancerPort, @FormParam("Listeners.member.1.LoadBalancerPort") int loadBalancerPort,
@FormParam("Listeners.member.1.InstancePort") int instancePort, @FormParam("Listeners.member.1.InstancePort") int instancePort,
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) String... availabilityZones); @BinderParam(BindAvailabilityZonesToIndexedFormParams.class) String... availabilityZones);
@ -90,10 +92,10 @@ public interface ELBAsyncClient {
@Path("/") @Path("/")
@XMLResponseParser(RegisterInstancesWithLoadBalancerResponseHandler.class) @XMLResponseParser(RegisterInstancesWithLoadBalancerResponseHandler.class)
@FormParams(keys = ACTION, values = "RegisterInstancesWithLoadBalancer") @FormParams(keys = ACTION, values = "RegisterInstancesWithLoadBalancer")
ListenableFuture<? extends Set<String>> registerInstancesWithLoadBalancerInRegion( ListenableFuture<Set<String>> registerInstancesWithLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name, @FormParam("LoadBalancerName") String name,
@BinderParam(BindELBInstanceIdsToIndexedFormParams.class) String... instanceIds); @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/** /**
* @see ELBClient#deregisterInstancesWithLoadBalancerInRegion * @see ELBClient#deregisterInstancesWithLoadBalancerInRegion
@ -104,7 +106,7 @@ public interface ELBAsyncClient {
ListenableFuture<Void> deregisterInstancesWithLoadBalancerInRegion( ListenableFuture<Void> deregisterInstancesWithLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name, @FormParam("LoadBalancerName") String name,
@BinderParam(BindELBInstanceIdsToIndexedFormParams.class) String... instanceIds); @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/** /**
* @see ELBClient#describeLoadBalancersInRegion * @see ELBClient#describeLoadBalancersInRegion
@ -113,7 +115,9 @@ public interface ELBAsyncClient {
@Path("/") @Path("/")
@XMLResponseParser(DescribeLoadBalancersResponseHandler.class) @XMLResponseParser(DescribeLoadBalancersResponseHandler.class)
@FormParams(keys = ACTION, values = "DescribeLoadBalancers") @FormParams(keys = ACTION, values = "DescribeLoadBalancers")
ListenableFuture<? extends Set<LoadBalancer>> describeLoadBalancersInRegion( @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); ListenableFuture<Set<? extends LoadBalancer>> describeLoadBalancersInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@BinderParam(BindLoadBalancerNamesToIndexedFormParams.class) String... loadbalancerNames);
} }

View File

@ -17,15 +17,15 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb; package org.jclouds.elb;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.elb.domain.LoadBalancer;
/** /**
* Provides access to EC2 Elastic Load Balancer via their REST API. * Provides access to EC2 Elastic Load Balancer via their REST API.
@ -97,8 +97,9 @@ public interface ELBClient {
/** /**
* Returns a set of elastic load balancers * Returns a set of elastic load balancers
* @param region * @param region
* @param loadbalancerNames names associated with the LoadBalancers at creation time.
* @return * @return
*/ */
Set<LoadBalancer> describeLoadBalancersInRegion(@Nullable String region); Set<? extends LoadBalancer> describeLoadBalancersInRegion(@Nullable String region, String... loadbalancerNames);
} }

View File

@ -17,13 +17,13 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb; package org.jclouds.elb;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import org.jclouds.aws.elb.config.ELBRestClientModule; import org.jclouds.elb.config.ELBRestClientModule;
import org.jclouds.aws.elb.loadbalancer.config.ELBLoadBalancerContextModule; import org.jclouds.elb.loadbalancer.config.ELBLoadBalancerContextModule;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.loadbalancer.LoadBalancerServiceContextBuilder; import org.jclouds.loadbalancer.LoadBalancerServiceContextBuilder;
import org.jclouds.logging.jdk.config.JDKLoggingModule; import org.jclouds.logging.jdk.config.JDKLoggingModule;

View File

@ -17,13 +17,14 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb; package org.jclouds.elb;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_ZONECLIENT_ENDPOINT;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;
@ -44,10 +45,9 @@ public class ELBPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_AUTH_TAG, "AWS"); properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz"); properties.setProperty(PROPERTY_HEADER_TAG, "amz");
properties.setProperty(PROPERTY_API_VERSION, ELBAsyncClient.VERSION); properties.setProperty(PROPERTY_API_VERSION, ELBAsyncClient.VERSION);
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_EAST_1, properties.setProperty(PROPERTY_REGIONS,
Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1)); Joiner.on(',').join(Region.US_EAST_1, Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT, properties.setProperty(PROPERTY_ENDPOINT, "https://elasticloadbalancing.us-east-1.amazonaws.com");
"https://elasticloadbalancing.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1, properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
"https://elasticloadbalancing.us-east-1.amazonaws.com"); "https://elasticloadbalancing.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1, properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
@ -56,6 +56,7 @@ public class ELBPropertiesBuilder extends PropertiesBuilder {
"https://elasticloadbalancing.eu-west-1.amazonaws.com"); "https://elasticloadbalancing.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1, properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://elasticloadbalancing.ap-southeast-1.amazonaws.com"); "https://elasticloadbalancing.ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_ZONECLIENT_ENDPOINT, "https://ec2.us-east-1.amazonaws.com");
return properties; return properties;
} }

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.binders; package org.jclouds.elb.binders;
import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithStringFormat; import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithStringFormat;

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.binders; package org.jclouds.elb.binders;
import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithStringFormat; import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithStringFormat;
@ -32,7 +32,7 @@ import org.jclouds.rest.Binder;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class BindELBInstanceIdsToIndexedFormParams 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); return indexStringArrayToFormValuesWithStringFormat(request, "Instances.member.%s.InstanceId", input);

View File

@ -0,0 +1,22 @@
package org.jclouds.elb.binders;
import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithStringFormat;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the String [] to form parameters named with LoadBalancerNames.member.index
*
* @author Adrian Cole
*/
@Singleton
public class BindLoadBalancerNamesToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return indexStringArrayToFormValuesWithStringFormat(request, "LoadBalancerNames.member.%s", input);
}
}

View File

@ -17,11 +17,11 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.config; package org.jclouds.elb.config;
import org.jclouds.aws.config.AWSFormSigningRestClientModule; import org.jclouds.aws.config.WithZonesFormSigningRestClientModule;
import org.jclouds.aws.elb.ELBAsyncClient; import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.aws.elb.ELBClient; import org.jclouds.elb.ELBClient;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
@ -32,7 +32,7 @@ import org.jclouds.rest.ConfiguresRestClient;
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class ELBRestClientModule extends AWSFormSigningRestClientModule<ELBClient, ELBAsyncClient> { public class ELBRestClientModule extends WithZonesFormSigningRestClientModule<ELBClient, ELBAsyncClient> {
public ELBRestClientModule() { public ELBRestClientModule() {
super(ELBClient.class, ELBAsyncClient.class); super(ELBClient.class, ELBAsyncClient.class);
} }

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.domain; package org.jclouds.elb.domain;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -45,9 +45,8 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
this.loadBalancerListeners = new HashSet<LoadBalancerListener>(); this.loadBalancerListeners = new HashSet<LoadBalancerListener>();
} }
public LoadBalancer(String region, String name, Set<String> instanceIds, public LoadBalancer(String region, String name, Set<String> instanceIds, Set<String> availabilityZones,
Set<String> availabilityZones, String dnsName) { String dnsName) {
super();
this.region = region; this.region = region;
this.name = name; this.name = name;
this.instanceIds = instanceIds; this.instanceIds = instanceIds;
@ -125,19 +124,24 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
return name.compareTo(that.name); 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 @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result result = prime * result + ((appCookieStickinessPolicy == null) ? 0 : appCookieStickinessPolicy.hashCode());
+ ((appCookieStickinessPolicy == null) ? 0 : appCookieStickinessPolicy.hashCode());
result = prime * result + ((availabilityZones == null) ? 0 : availabilityZones.hashCode()); result = prime * result + ((availabilityZones == null) ? 0 : availabilityZones.hashCode());
result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode());
result = prime * result + ((instanceIds == null) ? 0 : instanceIds.hashCode()); result = prime * result + ((instanceIds == null) ? 0 : instanceIds.hashCode());
result = prime * result result = prime * result + ((lBCookieStickinessPolicy == null) ? 0 : lBCookieStickinessPolicy.hashCode());
+ ((lBCookieStickinessPolicy == null) ? 0 : lBCookieStickinessPolicy.hashCode()); result = prime * result + ((loadBalancerListeners == null) ? 0 : loadBalancerListeners.hashCode());
result = prime * result
+ ((loadBalancerListeners == null) ? 0 : loadBalancerListeners.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode());
return result; return result;
@ -234,6 +238,11 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
return result; return result;
} }
@Override
public String toString() {
return "[policyName=" + policyName + ", cookieName=" + cookieName + "]";
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
@ -292,8 +301,7 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result result = prime * result + ((cookieExpirationPeriod == null) ? 0 : cookieExpirationPeriod.hashCode());
+ ((cookieExpirationPeriod == null) ? 0 : cookieExpirationPeriod.hashCode());
result = prime * result + ((policyName == null) ? 0 : policyName.hashCode()); result = prime * result + ((policyName == null) ? 0 : policyName.hashCode());
return result; return result;
} }
@ -320,6 +328,11 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
return true; return true;
} }
@Override
public String toString() {
return "[policyName=" + policyName + ", cookieExpirationPeriod=" + cookieExpirationPeriod + "]";
}
} }
public static class LoadBalancerListener { public static class LoadBalancerListener {
@ -328,8 +341,8 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
private Integer loadBalancerPort; private Integer loadBalancerPort;
private String protocol; private String protocol;
public LoadBalancerListener(Set<String> policyNames, Integer instancePort, public LoadBalancerListener(Set<String> policyNames, Integer instancePort, Integer loadBalancerPort,
Integer loadBalancerPort, String protocol) { String protocol) {
super(); super();
this.policyNames = policyNames; this.policyNames = policyNames;
this.instancePort = instancePort; this.instancePort = instancePort;
@ -416,5 +429,11 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
return true; return true;
} }
@Override
public String toString() {
return "[policyNames=" + policyNames + ", instancePort=" + instancePort + ", loadBalancerPort="
+ loadBalancerPort + ", protocol=" + protocol + "]";
}
} }
} }

View File

@ -0,0 +1,56 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.config;
import org.jclouds.elb.loadbalancer.strategy.ELBDestroyLoadBalancerStrategy;
import org.jclouds.elb.loadbalancer.strategy.ELBGetLoadBalancerMetadataStrategy;
import org.jclouds.elb.loadbalancer.strategy.ELBListLoadBalancersStrategy;
import org.jclouds.elb.loadbalancer.strategy.ELBLoadBalanceNodesStrategy;
import org.jclouds.loadbalancer.config.BindLoadBalancerStrategiesByClass;
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy;
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
/**
* @author Adrian Cole
*/
public class ELBBindLoadBalancerStrategiesByClass extends BindLoadBalancerStrategiesByClass {
@Override
protected Class<? extends LoadBalanceNodesStrategy> defineLoadBalanceNodesStrategy() {
return ELBLoadBalanceNodesStrategy.class;
}
@Override
protected Class<? extends DestroyLoadBalancerStrategy> defineDestroyLoadBalancerStrategy() {
return ELBDestroyLoadBalancerStrategy.class;
}
@Override
protected Class<? extends GetLoadBalancerMetadataStrategy> defineGetLoadBalancerMetadataStrategy() {
return ELBGetLoadBalancerMetadataStrategy.class;
}
@Override
protected Class<? extends ListLoadBalancersStrategy> defineListLoadBalancersStrategy() {
return ELBListLoadBalancersStrategy.class;
}
}

View File

@ -0,0 +1,45 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.config;
import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.loadbalancer.config.BindLoadBalancerSuppliersByClass;
import org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.ZoneToRegionToProvider;
import com.google.common.base.Supplier;
/**
* @author Adrian Cole
*/
public class ELBBindLoadBalancerSuppliersByClass extends BindLoadBalancerSuppliersByClass {
@Override
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return FirstZoneOrRegionMatchingRegionId.class;
}
@Override
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return ZoneToRegionToProvider.class;
}
}

View File

@ -17,30 +17,23 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.loadbalancer.config; package org.jclouds.elb.loadbalancer.config;
import org.jclouds.aws.elb.loadbalancer.strategy.ELBDestroyLoadBalancerStrategy; import org.jclouds.loadbalancer.config.BaseLoadBalancerServiceContextModule;
import org.jclouds.aws.elb.loadbalancer.strategy.ELBLoadBalanceNodesStrategy;
import org.jclouds.http.RequiresHttp;
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.inject.AbstractModule;
/** /**
* Configures the ELB connection. * Configures the ELB connection.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@RequiresHttp
@ConfiguresRestClient
public class ELBLoadBalancerContextModule extends AbstractModule {
public class ELBLoadBalancerContextModule extends BaseLoadBalancerServiceContextModule {
@Override @Override
protected void configure() { protected void configure() {
bind(LoadBalanceNodesStrategy.class).to(ELBLoadBalanceNodesStrategy.class); install(new ELBBindLoadBalancerSuppliersByClass());
bind(DestroyLoadBalancerStrategy.class).to(ELBDestroyLoadBalancerStrategy.class); install(new ELBBindLoadBalancerStrategiesByClass());
install(new ELBLoadBalancerServiceDependenciesModule());
super.configure();
} }
} }

View File

@ -0,0 +1,23 @@
package org.jclouds.elb.loadbalancer.config;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.loadbalancer.functions.LoadBalancerToLoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import com.google.common.base.Function;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
public class ELBLoadBalancerServiceDependenciesModule extends AbstractModule {
@Override
protected void configure() {
bind(new TypeLiteral<Function<LoadBalancer, LoadBalancerMetadata>>() {
}).to(LoadBalancerToLoadBalancerMetadata.class);
}
}

View File

@ -0,0 +1,59 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.functions;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Location;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerType;
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Singleton
public class LoadBalancerToLoadBalancerMetadata implements Function<LoadBalancer, LoadBalancerMetadata> {
protected final Supplier<Map<String, ? extends Location>> locationMap;
@Inject
public LoadBalancerToLoadBalancerMetadata(Supplier<Map<String, ? extends Location>> locationMap) {
this.locationMap = locationMap;
}
@Override
public LoadBalancerMetadata apply(LoadBalancer input) {
Location location = locationMap.get().get(input.getRegion());
// TODO Builder
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, input.getName(), input.getName(), input.getRegion()
+ "/" + input.getName(), location, null, ImmutableMap.<String, String> of(), ImmutableSet.of(input
.getDnsName()));
}
}

View File

@ -17,21 +17,21 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.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 org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.util.EC2Utils; import org.jclouds.elb.ELBClient;
import org.jclouds.aws.elb.ELBClient; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy; import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
/** /**
@ -45,19 +45,20 @@ public class ELBDestroyLoadBalancerStrategy implements DestroyLoadBalancerStrate
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final ELBClient elbClient; private final ELBClient elbClient;
private final GetLoadBalancerMetadataStrategy getLoadBalancer;
@Inject @Inject
protected ELBDestroyLoadBalancerStrategy(ELBClient elbClient) { protected ELBDestroyLoadBalancerStrategy(ELBClient elbClient, GetLoadBalancerMetadataStrategy getLoadBalancer) {
this.elbClient = checkNotNull(elbClient, "elbClient"); this.elbClient = checkNotNull(elbClient, "elbClient");
this.getLoadBalancer = checkNotNull(getLoadBalancer, "getLoadBalancer");
} }
@Override @Override
public boolean execute(String loadBalancer) { public LoadBalancerMetadata destroyLoadBalancer(String id) {
Map<String, String> tuple = EC2Utils.getLoadBalancerNameAndRegionFromDnsName(loadBalancer); String[] parts = parseHandle(id);
// Only one load balancer per DNS name is expected String region = parts[0];
for (String key : tuple.keySet()) { String instanceId = parts[1];
elbClient.deleteLoadBalancerInRegion(key, tuple.get(key)); elbClient.deleteLoadBalancerInRegion(region, instanceId);
} return getLoadBalancer.getLoadBalancer(id);
return true;
} }
} }

View File

@ -0,0 +1,47 @@
package org.jclouds.elb.loadbalancer.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
import java.util.NoSuchElementException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
import com.google.common.base.Function;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ELBGetLoadBalancerMetadataStrategy implements GetLoadBalancerMetadataStrategy {
private final ELBClient client;
private final Function<LoadBalancer, LoadBalancerMetadata> converter;
@Inject
protected ELBGetLoadBalancerMetadataStrategy(ELBClient client, Function<LoadBalancer, LoadBalancerMetadata> converter) {
this.client = checkNotNull(client, "client");
this.converter = checkNotNull(converter, "converter");
}
@Override
public LoadBalancerMetadata getLoadBalancer(String id) {
String[] parts = parseHandle(id);
String region = parts[0];
String instanceId = parts[1];
try {
return converter.apply(getOnlyElement(client.describeLoadBalancersInRegion(region, region, instanceId)));
} catch (NoSuchElementException e) {
return null;
}
}
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy;
import org.jclouds.location.Region;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.util.concurrent.ListenableFuture;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy {
@Resource
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
protected Logger logger = Logger.NULL;
private final ELBClient client;
private final ELBAsyncClient aclient;
private final Function<LoadBalancer, LoadBalancerMetadata> converter;
private final ExecutorService executor;
private final Set<String> regions;
@Inject
protected ELBListLoadBalancersStrategy(ELBClient client, ELBAsyncClient aclient,
Function<LoadBalancer, LoadBalancerMetadata> converter,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Nullable @Region Set<String> regions) {
this.client = checkNotNull(client, "client");
this.aclient = checkNotNull(aclient, "aclient");
this.regions = checkNotNull(regions, "regions");
this.converter = checkNotNull(converter, "converter");
this.executor = checkNotNull(executor, "executor");
}
@Override
public Iterable<? extends LoadBalancerMetadata> listLoadBalancers() {
Iterable<? extends LoadBalancer> loadBalancers;
if (regions != null)
loadBalancers = concat(transformParallel(regions, new Function<String, Future<Set<? extends LoadBalancer>>>() {
@Override
public ListenableFuture<Set<? extends LoadBalancer>> apply(String from) {
return aclient.describeLoadBalancersInRegion(from);
}
}, executor, null, logger, "loadbalancers"));
else
loadBalancers = client.describeLoadBalancersInRegion(null);
return transform(loadBalancers, converter);
}
}

View File

@ -17,7 +17,10 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.loadbalancer.strategy; package org.jclouds.elb.loadbalancer.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.compute.util.EC2ComputeUtils.getRegionFromLocationOrNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -28,21 +31,16 @@ import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.aws.ec2.util.EC2Utils.GetRegionFromLocation;
import org.jclouds.aws.elb.ELBClient;
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.domain.LoadBalancer;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.domain.LoadBalancerType;
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
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.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -55,23 +53,32 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
@Resource @Resource
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER) @Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final ELBClient elbClient; protected final ELBClient client;
protected final GetRegionFromLocation getRegionFromLocation; protected final Function<LoadBalancer, LoadBalancerMetadata> converter;
@Inject @Inject
protected ELBLoadBalanceNodesStrategy(ELBClient elbClient, GetRegionFromLocation getRegionFromLocation) { protected ELBLoadBalanceNodesStrategy(ELBClient client, Function<LoadBalancer, LoadBalancerMetadata> converter) {
this.elbClient = elbClient; this.client = checkNotNull(client, "client");
this.getRegionFromLocation = getRegionFromLocation; this.converter = checkNotNull(converter, "converter");
} }
@Override @Override
public LoadBalancerMetadata execute(Location location, String name, String protocol, int loadBalancerPort, public LoadBalancerMetadata createLoadBalancerInLocation(Location location, String name, String protocol,
int instancePort, Iterable<? extends NodeMetadata> nodes) { int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) {
String region = getRegionFromLocation.apply(location); checkNotNull(location, "location");
String dnsName = new String(); String region = getRegionFromLocationOrNull(location);
dnsName = elbClient.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort, List<String> availabilityZones = Lists.newArrayList(Iterables.transform(nodes,
EC2Utils.getAvailabilityZonesForRegion(region)); new Function<NodeMetadata, String>() {
@Override
public String apply(NodeMetadata from) {
return from.getLocation().getId();
}
}));
client.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort,
availabilityZones.toArray(new String[] {}));
List<String> instanceIds = Lists.newArrayList(Iterables.transform(nodes, new Function<NodeMetadata, String>() { List<String> instanceIds = Lists.newArrayList(Iterables.transform(nodes, new Function<NodeMetadata, String>() {
@ -83,7 +90,7 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
String[] instanceIdArray = instanceIds.toArray(new String[] {}); String[] instanceIdArray = instanceIds.toArray(new String[] {});
Set<String> registeredInstanceIds = elbClient.registerInstancesWithLoadBalancerInRegion(region, name, Set<String> registeredInstanceIds = client.registerInstancesWithLoadBalancerInRegion(region, name,
instanceIdArray); instanceIdArray);
// deregister instances // deregister instances
@ -95,10 +102,8 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
instanceIdArray[i] = list.get(i); instanceIdArray[i] = list.get(i);
} }
if (instanceIdArray.length > 0) if (instanceIdArray.length > 0)
elbClient.deregisterInstancesWithLoadBalancerInRegion(region, name, instanceIdArray); client.deregisterInstancesWithLoadBalancerInRegion(region, name, instanceIdArray);
} }
return converter.apply(Iterables.getOnlyElement(client.describeLoadBalancersInRegion(region, name)));
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, dnsName, name, dnsName, location, null,
ImmutableMap.<String, String> of(), ImmutableSet.of(dnsName));
} }
} }

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.xml; package org.jclouds.elb.xml;
import javax.annotation.Resource; import javax.annotation.Resource;

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.xml; package org.jclouds.elb.xml;
import java.util.Set; import java.util.Set;
@ -25,14 +25,13 @@ import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.aws.ec2.util.EC2Utils; import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.aws.elb.domain.LoadBalancer.AppCookieStickinessPolicy;
import org.jclouds.aws.elb.domain.LoadBalancer.LBCookieStickinessPolicy;
import org.jclouds.aws.elb.domain.LoadBalancer.LoadBalancerListener;
import org.jclouds.date.DateService; import org.jclouds.date.DateService;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.domain.LoadBalancer.AppCookieStickinessPolicy;
import org.jclouds.elb.domain.LoadBalancer.LBCookieStickinessPolicy;
import org.jclouds.elb.domain.LoadBalancer.LoadBalancerListener;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -44,22 +43,20 @@ import com.google.common.collect.Sets;
*/ */
public class DescribeLoadBalancersResponseHandler extends public class DescribeLoadBalancersResponseHandler extends
ParseSax.HandlerForGeneratedRequestWithResult<Set<LoadBalancer>> { ParseSax.HandlerForGeneratedRequestWithResult<Set<LoadBalancer>> {
@Inject private final DateService dateService;
public DescribeLoadBalancersResponseHandler(@Region String defaultRegion) { private final LoadBalancerListenerHandler listenerHandler;
this.defaultRegion = defaultRegion;
this.listenerHandler = new LoadBalancerListenerHandler();
}
@Inject @Inject
protected DateService dateService; public DescribeLoadBalancersResponseHandler(DateService dateService, LoadBalancerListenerHandler listenerHandler) {
this.dateService = dateService;
this.listenerHandler = listenerHandler;
}
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private Set<LoadBalancer> contents = Sets.newLinkedHashSet(); private Set<LoadBalancer> contents = Sets.newLinkedHashSet();
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
private final String defaultRegion;
private final LoadBalancerListenerHandler listenerHandler;
private boolean inListenerDescriptions = false; private boolean inListenerDescriptions = false;
private boolean inInstances = false; private boolean inInstances = false;
@ -92,8 +89,7 @@ public class DescribeLoadBalancersResponseHandler extends
} }
if (qName.equals("member")) { if (qName.equals("member")) {
if (!(inListenerDescriptions || inAppCookieStickinessPolicies || inInstances if (!(inListenerDescriptions || inAppCookieStickinessPolicies || inInstances || inLBCookieStickinessPolicies || inAvailabilityZones)) {
|| inLBCookieStickinessPolicies || inAvailabilityZones)) {
elb = new LoadBalancer(); elb = new LoadBalancer();
} }
} }
@ -131,9 +127,6 @@ public class DescribeLoadBalancersResponseHandler extends
|| inLBCookieStickinessPolicies || inAvailabilityZones)) { || inLBCookieStickinessPolicies || inAvailabilityZones)) {
try { try {
String region = EC2Utils.findRegionInArgsOrNull(getRequest()); String region = EC2Utils.findRegionInArgsOrNull(getRequest());
if (region == null)
region = defaultRegion;
elb.setRegion(region); elb.setRegion(region);
contents.add(elb); contents.add(elb);
} catch (NullPointerException e) { } catch (NullPointerException e) {
@ -165,8 +158,7 @@ public class DescribeLoadBalancersResponseHandler extends
return this; return this;
} }
public class LoadBalancerListenerHandler extends public static class LoadBalancerListenerHandler extends ParseSax.HandlerWithResult<Set<LoadBalancerListener>> {
ParseSax.HandlerWithResult<Set<LoadBalancerListener>> {
private Set<LoadBalancerListener> listeners = Sets.newHashSet(); private Set<LoadBalancerListener> listeners = Sets.newHashSet();
private StringBuilder currentText = new StringBuilder(); private StringBuilder currentText = new StringBuilder();
private LoadBalancerListener listener; private LoadBalancerListener listener;

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.xml; package org.jclouds.elb.xml;
import java.util.Set; import java.util.Set;

View File

@ -0,0 +1,192 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 java.util.Properties;
import javax.inject.Named;
import org.jclouds.Constants;
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.RequiresHttp;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
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 RestClientTest<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,
"Version=2010-07-01&Action=CreateLoadBalancer&Listeners.member.1.Protocol=http&LoadBalancerName=name&Listeners.member.1.InstancePort=80&Listeners.member.1.LoadBalancerPort=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, (String) null);
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, "Version=2010-07-01&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,
"Version=2010-07-01&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,
"Version=2010-07-01&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,
"Version=2010-07-01&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>>() {
};
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestELBRestClientModule extends ELBRestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(final DateService dateService,
@Named(Constants.PROPERTY_SESSION_INTERVAL) int expiration) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestELBRestClientModule();
}
@Override
public RestContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("elb", "identity", "credential", new Properties());
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), FormSigner.class);
}
}

View File

@ -17,22 +17,22 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb; package org.jclouds.elb;
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.Entry;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.elb.domain.LoadBalancer; import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.LoadBalancerServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterTest; import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -62,9 +62,8 @@ public class ELBClientLiveTest {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential"); + ".credential");
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider apiversion = System.getProperty("test." + provider + ".apiversion");
+ ".apiversion");
} }
protected Properties setupProperties() { protected Properties setupProperties() {
@ -72,8 +71,11 @@ public class ELBClientLiveTest {
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");
overrides.setProperty(provider + ".identity", identity); overrides.setProperty(provider + ".identity", identity);
if (credential != null)
overrides.setProperty(provider + ".credential", credential); overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint); overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion); overrides.setProperty(provider + ".apiversion", apiversion);
return overrides; return overrides;
} }
@ -82,8 +84,8 @@ public class ELBClientLiveTest {
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()), context = new LoadBalancerServiceContextFactory().createContext(provider,
overrides); ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
client = context.getApi(); client = context.getApi();
} }
@ -93,8 +95,8 @@ public class ELBClientLiveTest {
for (Entry<String, String> regionZone : ImmutableMap.<String, String> of(Region.US_EAST_1, for (Entry<String, String> regionZone : ImmutableMap.<String, String> of(Region.US_EAST_1,
AvailabilityZone.US_EAST_1A, Region.US_WEST_1, AvailabilityZone.US_WEST_1A, Region.EU_WEST_1, AvailabilityZone.US_EAST_1A, Region.US_WEST_1, AvailabilityZone.US_WEST_1A, Region.EU_WEST_1,
AvailabilityZone.EU_WEST_1A, Region.AP_SOUTHEAST_1, AvailabilityZone.AP_SOUTHEAST_1A).entrySet()) { AvailabilityZone.EU_WEST_1A, Region.AP_SOUTHEAST_1, AvailabilityZone.AP_SOUTHEAST_1A).entrySet()) {
String dnsName = client.createLoadBalancerInRegion(regionZone.getKey(), name, "http", 80, 80, regionZone String dnsName = client.createLoadBalancerInRegion(regionZone.getKey(), name, "http", 80, 80,
.getValue()); regionZone.getValue());
assertNotNull(dnsName); assertNotNull(dnsName);
assert (dnsName.startsWith(name)); assert (dnsName.startsWith(name));
} }
@ -104,7 +106,7 @@ public class ELBClientLiveTest {
void testDescribeLoadBalancers() { void testDescribeLoadBalancers() {
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
Region.AP_SOUTHEAST_1)) { Region.AP_SOUTHEAST_1)) {
Set<LoadBalancer> allResults = client.describeLoadBalancersInRegion(region); Set<? extends LoadBalancer> allResults = client.describeLoadBalancersInRegion(region);
assertNotNull(allResults); assertNotNull(allResults);
assert (allResults.size() >= 1); assert (allResults.size() >= 1);
} }

View File

@ -0,0 +1,41 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 org.jclouds.rest.Providers;
import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*
*/
@Test(groups = "unit")
public class ProvidersInPropertiesTest {
@Test
public void testSupportedProviders() {
Iterable<String> providers = Providers.getSupportedProviders();
assert Iterables.contains(providers, "elb") : providers;
}
}

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.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 static org.testng.Assert.assertNotNull;
@ -26,14 +26,13 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.elb.ELBAsyncClient;
import org.jclouds.aws.elb.ELBClient;
import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient;
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.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -43,9 +42,7 @@ import org.testng.annotations.Test;
@Test(groups = "live", sequential = true) @Test(groups = "live", sequential = true)
public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest { public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest {
@BeforeClass public ELBLoadBalancerServiceLiveTest() {
@Override
public void setServiceDefaults() {
provider = "elb"; provider = "elb";
computeProvider = "ec2"; computeProvider = "ec2";
} }
@ -66,7 +63,7 @@ public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT
for (NodeMetadata node : nodes) { for (NodeMetadata node : nodes) {
instanceIds.add(node.getProviderId()); instanceIds.add(node.getProviderId());
} }
Set<LoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(Region.US_EAST_1); Set<? extends LoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(Region.US_EAST_1);
assertNotNull(elbs); assertNotNull(elbs);
for (LoadBalancer elb : elbs) { for (LoadBalancer elb : elbs) {
if (elb.getName().equals(tag)) if (elb.getName().equals(tag))

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.xml; package org.jclouds.elb.xml;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.createMock;
@ -27,8 +27,8 @@ 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.aws.ec2.xml.BaseEC2HandlerTest; import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.aws.elb.domain.LoadBalancer; import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -42,16 +42,16 @@ import com.google.common.collect.Sets;
* *
* @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 = "DescribeLoadBalancerResponseHandlerTest") @Test(groups = "unit", testName = "DescribeLoadBalancerResponseHandlerTest")
public class DescribeLoadBalancerResponseHandlerTest extends BaseEC2HandlerTest { public class DescribeLoadBalancerResponseHandlerTest extends BaseHandlerTest {
public void testParse() { public void testParse() {
InputStream is = getClass().getResourceAsStream("/elb/describe_loadbalancers.xml"); InputStream is = getClass().getResourceAsStream("/describe_loadbalancers.xml");
Set<LoadBalancer> contents = Sets.newHashSet(); Set<LoadBalancer> contents = Sets.newHashSet();
LoadBalancer dummy = new LoadBalancer(defaultRegion, "my-load-balancer", ImmutableSet.of( LoadBalancer dummy = new LoadBalancer(null, "my-load-balancer", ImmutableSet.of("i-5b33e630",
"i-5b33e630", "i-8f26d7e4", "i-5933e632"), ImmutableSet.of("us-east-1a"), "i-8f26d7e4", "i-5933e632"), ImmutableSet.of("us-east-1a"),
"my-load-balancer-1400212309.us-east-1.elb.amazonaws.com"); "my-load-balancer-1400212309.us-east-1.elb.amazonaws.com");
contents.add(dummy); contents.add(dummy);
@ -61,8 +61,7 @@ public class DescribeLoadBalancerResponseHandlerTest extends BaseEC2HandlerTest
} }
private Set<LoadBalancer> parseLoadBalancers(InputStream is) { private Set<LoadBalancer> parseLoadBalancers(InputStream is) {
DescribeLoadBalancersResponseHandler handler = injector DescribeLoadBalancersResponseHandler handler = injector.getInstance(DescribeLoadBalancersResponseHandler.class);
.getInstance(DescribeLoadBalancersResponseHandler.class);
addDefaultRegionToHandler(handler); addDefaultRegionToHandler(handler);
Set<LoadBalancer> result = factory.create(handler).parse(is); Set<LoadBalancer> result = factory.create(handler).parse(is);
return result; return result;
@ -70,7 +69,7 @@ public class DescribeLoadBalancerResponseHandlerTest extends BaseEC2HandlerTest
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) { private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class); GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(ImmutableList.<Object>of()); expect(request.getArgs()).andReturn(ImmutableList.<Object> of());
replay(request); replay(request);
handler.setContext(request); handler.setContext(request);
} }

View File

@ -17,14 +17,14 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.elb.xml; package org.jclouds.elb.xml;
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.aws.ec2.xml.BaseEC2HandlerTest; 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.Sets;
@ -34,13 +34,12 @@ import com.google.common.collect.Sets;
* *
* @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 = "RegisterInstancesWithLoadBalancerResponseHandlerTest")
public class RegisterInstancesWithLoadBalancerResponseHandlerTest extends BaseEC2HandlerTest { public class RegisterInstancesWithLoadBalancerResponseHandlerTest extends BaseHandlerTest {
public void testParse() { public void testParse() {
InputStream is = getClass().getResourceAsStream( InputStream is = getClass().getResourceAsStream("/register_instances_with_loadbalancer.xml");
"/ec2/register_instances_with_loadbalancer.xml");
Set<String> instanceIds = Sets.newHashSet(); Set<String> instanceIds = Sets.newHashSet();
instanceIds.add("i-6055fa09"); instanceIds.add("i-6055fa09");

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed 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.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="LOADBALANCERFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-loadbalancer.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<appender name="ASYNCLOADBALANCER" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="LOADBALANCERFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.loadbalancer">
<priority value="DEBUG" />
<appender-ref ref="ASYNCLOADBALANCER" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -19,7 +19,7 @@
package org.jclouds.simpledb.config; package org.jclouds.simpledb.config;
import org.jclouds.aws.config.AWSFormSigningRestClientModule; import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.simpledb.SimpleDBAsyncClient; import org.jclouds.simpledb.SimpleDBAsyncClient;
@ -33,7 +33,7 @@ import org.jclouds.simpledb.SimpleDBClient;
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class SimpleDBRestClientModule extends AWSFormSigningRestClientModule<SimpleDBClient, SimpleDBAsyncClient> { public class SimpleDBRestClientModule extends FormSigningRestClientModule<SimpleDBClient, SimpleDBAsyncClient> {
public SimpleDBRestClientModule() { public SimpleDBRestClientModule() {
super(SimpleDBClient.class, SimpleDBAsyncClient.class); super(SimpleDBClient.class, SimpleDBAsyncClient.class);

View File

@ -23,7 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;

View File

@ -21,7 +21,7 @@ package org.jclouds.aws.cloudwatch.config;
import org.jclouds.aws.cloudwatch.CloudWatchAsyncClient; import org.jclouds.aws.cloudwatch.CloudWatchAsyncClient;
import org.jclouds.aws.cloudwatch.CloudWatchClient; import org.jclouds.aws.cloudwatch.CloudWatchClient;
import org.jclouds.aws.config.AWSFormSigningRestClientModule; import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
@ -32,7 +32,7 @@ import org.jclouds.rest.ConfiguresRestClient;
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class CloudWatchRestClientModule extends AWSFormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> { public class CloudWatchRestClientModule extends FormSigningRestClientModule<CloudWatchClient, CloudWatchAsyncClient> {
public CloudWatchRestClientModule() { public CloudWatchRestClientModule() {
super(CloudWatchClient.class, CloudWatchAsyncClient.class); super(CloudWatchClient.class, CloudWatchAsyncClient.class);
} }

View File

@ -19,21 +19,14 @@
package org.jclouds.aws.config; package org.jclouds.aws.config;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.get; import static com.google.common.collect.Iterables.get;
import static com.google.common.collect.Maps.newLinkedHashMap;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler; import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent; import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
@ -49,16 +42,12 @@ import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Predicate; import com.google.common.collect.ImmutableBiMap;
import com.google.common.base.Splitter;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.name.Names; import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
/** /**
* Configures the S3 connection, including logging and http transport.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -74,56 +63,6 @@ public class AWSRestClientModule<S, A> extends RestClientModule<S, A> {
super(syncClientType, asyncClientType); super(syncClientType, asyncClientType);
} }
@Provides
@Singleton
@Region
@Nullable
protected Map<String, URI> provideRegions(Injector injector) {
try {
String regionString = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGIONS)));
Map<String, URI> regions = newLinkedHashMap();
for (String region : Splitter.on(',').split(regionString)) {
regions.put(
region,
URI.create(injector.getInstance(Key.get(String.class,
Names.named(Constants.PROPERTY_ENDPOINT + "." + region)))));
}
return regions;
} catch (ConfigurationException e) {
// this happens if regions property isn't set
// services not run by AWS may not have regions, so this is ok.
return null;
}
}
@Provides
@Singleton
@Region
protected Set<String> provideRegions(@Region Map<String, URI> map) {
return map.keySet();
}
@Provides
@Singleton
@Region
protected String getDefaultRegion(@Provider final URI uri, @Region Map<String, URI> map, LoggerFactory logFactory) {
try {
return find(map.entrySet(), new Predicate<Entry<String, URI>>() {
@Override
public boolean apply(Entry<String, URI> input) {
return input.getValue().equals(uri);
}
}).getKey();
} catch (NoSuchElementException e) {
String region = get(map.keySet(), 0);
logFactory.getLogger("jclouds.compute").warn(
"failed to find region for current endpoint %s in %s; choosing first: %s", uri, map, region);
return region;
}
}
@Override @Override
protected void bindErrorHandlers() { protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAWSErrorFromXmlContent.class); bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAWSErrorFromXmlContent.class);
@ -137,4 +76,39 @@ public class AWSRestClientModule<S, A> extends RestClientModule<S, A> {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class); bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AWSClientErrorRetryHandler.class);
} }
@Provides
@Singleton
@Region
protected String getDefaultRegion(@Provider URI uri, @Region Map<String, URI> map, LoggerFactory logFactory) {
String region = ImmutableBiMap.copyOf(map).inverse().get(uri);
if (region == null) {
logFactory.getLogger(getClass().getName()).warn(
"failed to find region for current endpoint %s in %s; choosing first: %s", uri, map, region);
region = get(map.keySet(), 0);
}
return region;
}
protected void bindRegionsToProvider() {
bindRegionsToProvider(ProvideRegionsViaProperties.class);
}
@Override
protected void configure() {
super.configure();
bindRegionsToProvider();
}
protected void bindRegionsToProvider(Class<? extends javax.inject.Provider<Map<String, URI>>> providerClass) {
bind(new TypeLiteral<Map<String, URI>>() {
}).annotatedWith(Region.class).toProvider(providerClass).in(Scopes.SINGLETON);
}
@Provides
@Singleton
@Region
protected Set<String> provideRegions(@Region Map<String, URI> map) {
return map.keySet();
}
} }

View File

@ -36,20 +36,19 @@ import org.jclouds.rest.RequestSigner;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
* Configures the S3 connection, including logging and http transport.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ConfiguresRestClient @ConfiguresRestClient
@RequiresHttp @RequiresHttp
public class AWSFormSigningRestClientModule<S, A> extends AWSRestClientModule<S, A> { public class FormSigningRestClientModule<S, A> extends AWSRestClientModule<S, A> {
public AWSFormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType, public FormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
Map<Class<?>, Class<?>> delegates) { Map<Class<?>, Class<?>> delegates) {
super(syncClientType, asyncClientType, delegates); super(syncClientType, asyncClientType, delegates);
} }
public AWSFormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) { public FormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
super(syncClientType, asyncClientType); super(syncClientType, asyncClientType);
} }

View File

@ -0,0 +1,55 @@
package org.jclouds.aws.config;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
@Singleton
public class ProvideRegionsViaProperties implements javax.inject.Provider<Map<String, URI>> {
private final Injector injector;
@Inject
ProvideRegionsViaProperties(Injector injector) {
this.injector = injector;
}
@Singleton
@Region
@Override
public Map<String, URI> get() {
try {
String regionString = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGIONS)));
Builder<String, URI> regions = ImmutableMap.<String, URI> builder();
for (String region : Splitter.on(',').split(regionString)) {
regions.put(
region,
URI.create(injector.getInstance(Key.get(String.class,
Names.named(Constants.PROPERTY_ENDPOINT + "." + region)))));
}
return regions.build();
} catch (ConfigurationException e) {
// this happens if regions property isn't set
// services not run by AWS may not have regions, so this is ok.
return ImmutableMap.of(injector.getInstance(Key.get(String.class, Provider.class)),
injector.getInstance(Key.get(URI.class, Provider.class)));
}
}
}

View File

@ -0,0 +1,168 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.config;
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
import org.jclouds.aws.ec2.xml.DescribeAvailabilityZonesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeRegionsResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.concurrent.Timeout;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.annotations.EndpointParam;
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.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public class ProvidersViaAPI {
@Singleton
public static class RegionIdsToURI implements javax.inject.Provider<Map<String, URI>> {
private final ZoneAndRegionClient client;
private URI endpoint;
@Inject
public RegionIdsToURI(@Zone URI endpoint, ZoneAndRegionClient client) {
this.client = client;
this.endpoint = endpoint;
}
@Singleton
@Region
@Override
public Map<String, URI> get() {
return client.describeRegions(endpoint);
}
}
@Singleton
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
private final ZoneAndRegionClient client;
private final Set<String> regions;
private final RegionIdsToURI regionIdsToURI;
@Inject
public RegionIdToZoneId(RegionIdsToURI regionIdsToURI, ZoneAndRegionClient client, @Region Set<String> regions) {
this.client = client;
this.regions = regions;
this.regionIdsToURI = regionIdsToURI;
}
@Singleton
@Zone
@Override
public Map<String, String> get() {
Builder<String, String> map = ImmutableMap.<String, String> builder();
for (Entry<String, URI> region : regionIdsToURI.get().entrySet()) {
if (regions.contains(region.getKey()))
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getValue())) {
map.put(zoneInfo.getZone(), region.getKey());
}
}
return map.build();
}
}
static class ProvidesZoneAndRegionClientModule extends AbstractModule {
@Provides
@Singleton
@Zone
URI provideURI(@Named(AWSConstants.PROPERTY_ZONECLIENT_ENDPOINT) String endpoint) {
return URI.create(endpoint);
}
@Provides
@Singleton
ZoneAndRegionClient provideZoneAndRegionClient(AsyncClientFactory factory) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.proxy(ZoneAndRegionClient.class,
new SyncProxy(ZoneAndRegionClient.class, factory.create(ZoneAndRegionAsyncClient.class),
new ConcurrentHashMap<ClassMethodArgs, Object>(), ImmutableMap.<Class<?>, Class<?>> of()));
}
@Override
protected void configure() {
}
}
@RequestFilters(FormSigner.class)
@FormParams(keys = "Version", values = "2010-06-15")
@VirtualHost
static interface ZoneAndRegionAsyncClient {
@POST
@Path("/")
@FormParams(keys = "Action", values = "DescribeAvailabilityZones")
@XMLResponseParser(DescribeAvailabilityZonesResponseHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<AvailabilityZoneInfo>> describeAvailabilityZonesInRegion(@EndpointParam URI region);
@POST
@Path("/")
@FormParams(keys = "Action", values = "DescribeRegions")
@XMLResponseParser(DescribeRegionsResponseHandler.class)
ListenableFuture<? extends Map<String, URI>> describeRegions(@EndpointParam URI endpoint);
}
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
static interface ZoneAndRegionClient {
Set<AvailabilityZoneInfo> describeAvailabilityZonesInRegion(URI region);
Map<String, URI> describeRegions(URI endpoint);
}
}

View File

@ -0,0 +1,88 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.config;
import java.net.URI;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.aws.config.ProvidersViaAPI.ProvidesZoneAndRegionClientModule;
import org.jclouds.http.RequiresHttp;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@ConfiguresRestClient
@RequiresHttp
public class WithZonesFormSigningRestClientModule<S, A> extends FormSigningRestClientModule<S, A> {
public WithZonesFormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
Map<Class<?>, Class<?>> delegates) {
super(syncClientType, asyncClientType, delegates);
}
public WithZonesFormSigningRestClientModule(Class<S> syncClientType, Class<A> asyncClientType) {
super(syncClientType, asyncClientType);
}
protected void bindZonesToProvider() {
install(new ProvidesZoneAndRegionClientModule());
bindZonesToProvider(ProvidersViaAPI.RegionIdToZoneId.class);
}
protected void bindZonesToProvider(Class<? extends javax.inject.Provider<Map<String, String>>> providerClass) {
bind(new TypeLiteral<Map<String, String>>() {
}).annotatedWith(Zone.class).toProvider(providerClass).in(Scopes.SINGLETON);
}
@Override
protected void configure() {
super.configure();
bindZonesToProvider();
}
@Provides
@Singleton
@Zone
protected Map<String, URI> provideZones(@Region final Map<String, URI> regionToEndpoint,
@Zone Map<String, String> availabilityZoneToRegion) {
return Maps.transformValues(availabilityZoneToRegion, new Function<String, URI>() {
@Override
public URI apply(String from) {
return regionToEndpoint.get(from);
}
});
}
}

View File

@ -23,11 +23,12 @@ import java.util.Set;
import org.jclouds.aws.ec2.compute.suppliers.EC2HardwareSupplier; import org.jclouds.aws.ec2.compute.suppliers.EC2HardwareSupplier;
import org.jclouds.aws.ec2.compute.suppliers.EC2ImageSupplier; import org.jclouds.aws.ec2.compute.suppliers.EC2ImageSupplier;
import org.jclouds.aws.ec2.compute.suppliers.EC2LocationSupplier;
import org.jclouds.compute.config.BindComputeSuppliersByClass; import org.jclouds.compute.config.BindComputeSuppliersByClass;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.ZoneToRegionToProvider;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
/** /**
@ -46,11 +47,11 @@ public class EC2BindComputeSuppliersByClass extends BindComputeSuppliersByClass
@Override @Override
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() { protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId.class; return FirstZoneOrRegionMatchingRegionId.class;
} }
@Override @Override
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() { protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return EC2LocationSupplier.class; return ZoneToRegionToProvider.class;
} }
} }

View File

@ -1,66 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.elb.ELBClient;
import org.jclouds.aws.elb.domain.LoadBalancer;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.ListLoadBalancersStrategy;
import org.jclouds.logging.Logger;
/**
*
* @author Adrian Cole
*/
@Singleton
public class EC2ListLoadBalancersStrategy implements ListLoadBalancersStrategy {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final ELBClient elbClient;
@Inject
protected EC2ListLoadBalancersStrategy(ELBClient elbClient) {
this.elbClient = checkNotNull(elbClient, "elbClient");
}
@Override
public Set<String> execute() {
Set<LoadBalancer> loadBalancers = elbClient.describeLoadBalancersInRegion(null);
Set<String> loadBalancerDnsNames = new HashSet<String>();
for(LoadBalancer loadBalancer: loadBalancers)
{
loadBalancerDnsNames.add(loadBalancer.getDnsName());
}
return loadBalancerDnsNames;
}
}

View File

@ -25,8 +25,6 @@ import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.collect.Sets.newLinkedHashSet;
import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.net.URI;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -62,16 +60,16 @@ public class EC2ListNodesStrategy implements ListNodesStrategy {
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final EC2AsyncClient client; private final EC2AsyncClient client;
private final Map<String, URI> regionMap; private final Set<String> regions;
private final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata; private final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
private final ExecutorService executor; private final ExecutorService executor;
@Inject @Inject
protected EC2ListNodesStrategy(EC2AsyncClient client, @Region Map<String, URI> regionMap, protected EC2ListNodesStrategy(EC2AsyncClient client, @Region Set<String> regions,
Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
this.client = client; this.client = client;
this.regionMap = regionMap; this.regions = regions;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata; this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
this.executor = executor; this.executor = executor;
} }
@ -84,7 +82,7 @@ public class EC2ListNodesStrategy implements ListNodesStrategy {
@Override @Override
public Set<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) { public Set<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
Iterable<Set<? extends Reservation<? extends RunningInstance>>> reservations = transformParallel( Iterable<Set<? extends Reservation<? extends RunningInstance>>> reservations = transformParallel(
regionMap.keySet(), new Function<String, Future<Set<? extends Reservation<? extends RunningInstance>>>>() { regions, new Function<String, Future<Set<? extends Reservation<? extends RunningInstance>>>>() {
@Override @Override
public Future<Set<? extends Reservation<? extends RunningInstance>>> apply(String from) { public Future<Set<? extends Reservation<? extends RunningInstance>>> apply(String from) {

View File

@ -42,16 +42,15 @@ import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.newLinkedHashMap;
import static com.google.common.collect.Maps.transformValues;
import static com.google.common.collect.Maps.uniqueIndex; import static com.google.common.collect.Maps.uniqueIndex;
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds; import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy; import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
@ -70,6 +69,8 @@ import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
/** /**
* *
@ -81,7 +82,7 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Map<String, URI> regionMap; private final Set<String> regions;
private final DescribeImagesParallel describer; private final DescribeImagesParallel describer;
private final String[] ccAmis; private final String[] ccAmis;
private final String[] amiOwners; private final String[] amiOwners;
@ -89,10 +90,10 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
private final Map<RegionAndName, Image> images; private final Map<RegionAndName, Image> images;
@Inject @Inject
RegionAndNameToImageSupplier(@Region Map<String, URI> regionMap, DescribeImagesParallel describer, RegionAndNameToImageSupplier(@Region Set<String> regions, DescribeImagesParallel describer,
@Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners, @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners,
final ImageParser parser, final Map<RegionAndName, Image> images) { final ImageParser parser, final Map<RegionAndName, Image> images) {
this.regionMap = regionMap; this.regions = regions;
this.describer = describer; this.describer = describer;
this.ccAmis = ccAmis; this.ccAmis = ccAmis;
this.amiOwners = amiOwners; this.amiOwners = amiOwners;
@ -108,7 +109,7 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
logger.debug(">> providing images"); logger.debug(">> providing images");
Iterable<Entry<String, DescribeImagesOptions>> queries = concat( Iterable<Entry<String, DescribeImagesOptions>> queries = concat(
getDescribeQueriesForOwnersInRegions(regionMap, amiOwners).entrySet(), ccAmisToDescribeQueries(ccAmis) getDescribeQueriesForOwnersInRegions(regions, amiOwners).entrySet(), ccAmisToDescribeQueries(ccAmis)
.entrySet()); .entrySet());
Iterable<? extends Image> parsedImages = filter(transform(describer.apply(queries), parser), Iterable<? extends Image> parsedImages = filter(transform(describer.apply(queries), parser),
@ -136,16 +137,13 @@ public class RegionAndNameToImageSupplier implements Supplier<Map<RegionAndName,
return queries; return queries;
} }
private static Map<String, DescribeImagesOptions> getDescribeQueriesForOwnersInRegions(Map<String, URI> regionMap, private static Map<String, DescribeImagesOptions> getDescribeQueriesForOwnersInRegions(Set<String> regions,
final String[] amiOwners) { final String[] amiOwners) {
final DescribeImagesOptions options = getOptionsForOwners(amiOwners); final DescribeImagesOptions options = getOptionsForOwners(amiOwners);
Builder<String, DescribeImagesOptions> builder = ImmutableMap.<String, DescribeImagesOptions> builder();
return transformValues(regionMap, new Function<URI, DescribeImagesOptions>() { for (String region : regions)
@Override builder.put(region, options);
public DescribeImagesOptions apply(URI from) { return builder.build();
return options;
}
});
} }
private static DescribeImagesOptions getOptionsForOwners(final String[] amiOwners) { private static DescribeImagesOptions getOptionsForOwners(final String[] amiOwners) {

View File

@ -21,10 +21,12 @@ package org.jclouds.aws.ec2.config;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.config.AWSFormSigningRestClientModule; import org.jclouds.aws.config.WithZonesFormSigningRestClientModule;
import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo; import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
@ -50,12 +52,11 @@ import org.jclouds.aws.ec2.services.WindowsAsyncClient;
import org.jclouds.aws.ec2.services.WindowsClient; import org.jclouds.aws.ec2.services.WindowsClient;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.ImmutableMap.Builder;
import com.google.inject.Injector;
import com.google.inject.Provides;
/** /**
* Configures the EC2 connection. * Configures the EC2 connection.
@ -64,7 +65,7 @@ import com.google.inject.Provides;
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class EC2RestClientModule extends AWSFormSigningRestClientModule<EC2Client, EC2AsyncClient> { public class EC2RestClientModule extends WithZonesFormSigningRestClientModule<EC2Client, EC2AsyncClient> {
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(AMIClient.class, AMIAsyncClient.class)// .put(AMIClient.class, AMIAsyncClient.class)//
@ -83,37 +84,57 @@ public class EC2RestClientModule extends AWSFormSigningRestClientModule<EC2Clien
super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
} }
private RuntimeException regionException = null; @Override
protected void bindRegionsToProvider() {
bindRegionsToProvider(RegionIdsToURI.class);
}
@Override @Override
protected Map<String, URI> provideRegions(Injector injector) { protected void bindZonesToProvider() {
// http://code.google.com/p/google-guice/issues/detail?id=483 bindZonesToProvider(RegionIdToZoneId.class);
// guice doesn't remember when singleton providers throw exceptions.
// in this case, if describeRegions fails, it is called again for
// each provider method that depends on it. To short-circuit this,
// we remember the last exception trusting that guice is single-threaded
if (regionException != null)
throw regionException;
EC2Client client = injector.getInstance(EC2Client.class);
try {
return client.getAvailabilityZoneAndRegionServices().describeRegions();
} catch (RuntimeException e) {
this.regionException = e;
throw e;
}
} }
@Provides
@Singleton @Singleton
protected Map<String, String> provideAvailabilityZoneToRegions(EC2Client client, @Region Map<String, URI> regions) { public static class RegionIdsToURI implements javax.inject.Provider<Map<String, URI>> {
Map<String, String> map = Maps.newHashMap(); private final AvailabilityZoneAndRegionClient client;
for (String region : regions.keySet()) {
for (AvailabilityZoneInfo zoneInfo : client.getAvailabilityZoneAndRegionServices() @Inject
.describeAvailabilityZonesInRegion(region)) { public RegionIdsToURI(EC2Client client) {
map.put(zoneInfo.getZone(), region); this.client = client.getAvailabilityZoneAndRegionServices();
}
@Singleton
@Region
@Override
public Map<String, URI> get() {
return client.describeRegions();
}
}
@Singleton
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
private final AvailabilityZoneAndRegionClient client;
private final Map<String, URI> regions;
@Inject
public RegionIdToZoneId(EC2Client client, @Region Map<String, URI> regions) {
this.client = client.getAvailabilityZoneAndRegionServices();
this.regions = regions;
}
@Singleton
@Zone
@Override
public Map<String, String> get() {
Builder<String, String> map = ImmutableMap.<String, String> builder();
for (Entry<String, URI> region : regions.entrySet()) {
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getKey())) {
map.put(zoneInfo.getZone(), region.getKey());
} }
} }
return map; return map.build();
}
} }
} }

View File

@ -37,7 +37,6 @@ import org.jclouds.aws.ec2.domain.Attachment;
import org.jclouds.aws.ec2.domain.Permission; import org.jclouds.aws.ec2.domain.Permission;
import org.jclouds.aws.ec2.domain.Snapshot; import org.jclouds.aws.ec2.domain.Snapshot;
import org.jclouds.aws.ec2.domain.Volume; import org.jclouds.aws.ec2.domain.Volume;
import org.jclouds.aws.ec2.functions.AvailabilityZoneToEndpoint;
import org.jclouds.aws.ec2.functions.ReturnVoidOnVolumeAvailable; import org.jclouds.aws.ec2.functions.ReturnVoidOnVolumeAvailable;
import org.jclouds.aws.ec2.options.CreateSnapshotOptions; import org.jclouds.aws.ec2.options.CreateSnapshotOptions;
import org.jclouds.aws.ec2.options.DescribeSnapshotsOptions; import org.jclouds.aws.ec2.options.DescribeSnapshotsOptions;
@ -50,6 +49,7 @@ import org.jclouds.aws.ec2.xml.PermissionHandler;
import org.jclouds.aws.ec2.xml.SnapshotHandler; import org.jclouds.aws.ec2.xml.SnapshotHandler;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.location.functions.ZoneToEndpoint;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
@ -80,7 +80,7 @@ public interface ElasticBlockStoreAsyncClient {
@FormParams(keys = ACTION, values = "CreateVolume") @FormParams(keys = ACTION, values = "CreateVolume")
@XMLResponseParser(CreateVolumeResponseHandler.class) @XMLResponseParser(CreateVolumeResponseHandler.class)
ListenableFuture<Volume> createVolumeFromSnapshotInAvailabilityZone( ListenableFuture<Volume> createVolumeFromSnapshotInAvailabilityZone(
@EndpointParam(parser = AvailabilityZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone, @EndpointParam(parser = ZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone,
@FormParam("SnapshotId") String snapshotId); @FormParam("SnapshotId") String snapshotId);
/** /**
@ -91,7 +91,7 @@ public interface ElasticBlockStoreAsyncClient {
@FormParams(keys = ACTION, values = "CreateVolume") @FormParams(keys = ACTION, values = "CreateVolume")
@XMLResponseParser(CreateVolumeResponseHandler.class) @XMLResponseParser(CreateVolumeResponseHandler.class)
ListenableFuture<Volume> createVolumeFromSnapshotInAvailabilityZone( ListenableFuture<Volume> createVolumeFromSnapshotInAvailabilityZone(
@EndpointParam(parser = AvailabilityZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone, @EndpointParam(parser = ZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone,
@FormParam("Size") int size, @FormParam("SnapshotId") String snapshotId); @FormParam("Size") int size, @FormParam("SnapshotId") String snapshotId);
/** /**
@ -102,7 +102,7 @@ public interface ElasticBlockStoreAsyncClient {
@FormParams(keys = ACTION, values = "CreateVolume") @FormParams(keys = ACTION, values = "CreateVolume")
@XMLResponseParser(CreateVolumeResponseHandler.class) @XMLResponseParser(CreateVolumeResponseHandler.class)
ListenableFuture<Volume> createVolumeInAvailabilityZone( ListenableFuture<Volume> createVolumeInAvailabilityZone(
@EndpointParam(parser = AvailabilityZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone, @EndpointParam(parser = ZoneToEndpoint.class) @FormParam("AvailabilityZone") String availabilityZone,
@FormParam("Size") int size); @FormParam("Size") int size);
/** /**

View File

@ -36,15 +36,20 @@ import org.jclouds.logging.Logger;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Attachment> { public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Attachment> {
private StringBuilder currentText = new StringBuilder();
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final String defaultRegion;
@Inject @Inject
protected DateService dateService; AttachmentHandler(DateService dateService, @Region String defaultRegion) {
@Inject this.dateService = dateService;
@Region this.defaultRegion = defaultRegion;
String defaultRegion; }
private StringBuilder currentText = new StringBuilder();
private String volumeId; private String volumeId;
private String instanceId; private String instanceId;
private String device; private String device;

View File

@ -35,6 +35,7 @@ import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
@ -56,6 +57,7 @@ public class CreateVolumeResponseHandler extends
@Region @Region
String defaultRegion; String defaultRegion;
@Inject @Inject
@Zone
protected Map<String, String> availabilityZoneToRegion; protected Map<String, String> availabilityZoneToRegion;
private String id; private String id;

View File

@ -93,7 +93,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
&& (error.getCode().equals("UnsupportedOperation"))) && (error.getCode().equals("UnsupportedOperation")))
exception = new UnsupportedOperationException(message, exception); exception = new UnsupportedOperationException(message, exception);
if (error != null && error.getCode() != null if (error != null && error.getCode() != null
&& (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown"))) && (error.getCode().endsWith("NotFound") || error.getCode().endsWith(".Unknown")))
exception = new ResourceNotFoundException(message, exception); exception = new ResourceNotFoundException(message, exception);
else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error
.getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1))) .getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1)))

View File

@ -25,8 +25,7 @@ package org.jclouds.aws.reference;
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface AWSConstants { public interface AWSConstants {
public static final String PROPERTY_REGIONS = "jclouds.aws.regions"; public static final String PROPERTY_ZONECLIENT_ENDPOINT = "jclouds.aws.zoneclient-endpoint";
public static final String PROPERTY_DEFAULT_REGIONS = "jclouds.aws.default_regions";
public static final String PROPERTY_AUTH_TAG = "jclouds.aws.auth.tag"; public static final String PROPERTY_AUTH_TAG = "jclouds.aws.auth.tag";
public static final String PROPERTY_HEADER_TAG = "jclouds.aws.header.tag"; public static final String PROPERTY_HEADER_TAG = "jclouds.aws.header.tag";
} }

View File

@ -21,9 +21,8 @@ package org.jclouds.aws.s3;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_DEFAULT_REGIONS;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;
@ -44,7 +43,6 @@ public class GoogleStoragePropertiesBuilder extends S3PropertiesBuilder {
@Override @Override
protected Properties addEndpoints(Properties properties) { protected Properties addEndpoints(Properties properties) {
properties.setProperty(PROPERTY_REGIONS, "GoogleStorage"); properties.setProperty(PROPERTY_REGIONS, "GoogleStorage");
properties.setProperty(PROPERTY_DEFAULT_REGIONS, "GoogleStorage");
properties.setProperty(PROPERTY_ENDPOINT, "https://commondatastorage.googleapis.com"); properties.setProperty(PROPERTY_ENDPOINT, "https://commondatastorage.googleapis.com");
properties.setProperty(PROPERTY_ENDPOINT + ".GoogleStorage", properties.setProperty(PROPERTY_ENDPOINT + ".GoogleStorage",
"https://commondatastorage.googleapis.com"); "https://commondatastorage.googleapis.com");

View File

@ -23,14 +23,13 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME; import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_DEFAULT_REGIONS;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS;
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER; import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;
@ -62,7 +61,6 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
protected Properties addEndpoints(Properties properties) { protected Properties addEndpoints(Properties properties) {
properties.setProperty(PROPERTY_REGIONS, properties.setProperty(PROPERTY_REGIONS,
Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1)); Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_DEFAULT_REGIONS, Region.US_STANDARD);
properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com"); properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_STANDARD, "https://s3.amazonaws.com"); properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_STANDARD, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1, "https://s3-us-west-1.amazonaws.com"); properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1, "https://s3-us-west-1.amazonaws.com");

View File

@ -21,10 +21,9 @@ package org.jclouds.aws.s3;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_DEFAULT_REGIONS;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS; import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;
@ -37,7 +36,6 @@ public class WalrusPropertiesBuilder extends S3PropertiesBuilder {
@Override @Override
protected Properties addEndpoints(Properties properties) { protected Properties addEndpoints(Properties properties) {
properties.setProperty(PROPERTY_REGIONS, "Walrus"); properties.setProperty(PROPERTY_REGIONS, "Walrus");
properties.setProperty(PROPERTY_DEFAULT_REGIONS, "Walrus");
properties.setProperty(PROPERTY_API_VERSION, "Walrus-1.6"); properties.setProperty(PROPERTY_API_VERSION, "Walrus-1.6");
properties.setProperty(PROPERTY_ENDPOINT, "http://ecc.eucalyptus.com:8773/services/Walrus"); properties.setProperty(PROPERTY_ENDPOINT, "http://ecc.eucalyptus.com:8773/services/Walrus");
properties.setProperty(PROPERTY_ENDPOINT + ".Walrus", properties.setProperty(PROPERTY_ENDPOINT + ".Walrus",

View File

@ -20,23 +20,18 @@
package org.jclouds.aws.s3.functions; package org.jclouds.aws.s3.functions;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_DEFAULT_REGIONS;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.aws.domain.Region;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.rest.binders.BindToStringPayload; import org.jclouds.rest.binders.BindToStringPayload;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
/** /**
* *
* Depending on your latency and legal requirements, you can specify a location constraint that will * Depending on your latency and legal requirements, you can specify a location constraint that will
@ -50,35 +45,31 @@ public class BindRegionToXmlPayload extends BindToStringPayload {
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final Iterable<String> defaultRegions; private final String defaultRegion;
private final Iterable<String> regions; private final Set<String> regions;
@Inject @Inject
BindRegionToXmlPayload(@Named(PROPERTY_DEFAULT_REGIONS) String defaultRegions, BindRegionToXmlPayload(@org.jclouds.location.Region String defaultRegion,
@Named(PROPERTY_REGIONS) String regions) { @org.jclouds.location.Region Set<String> regions) {
this.defaultRegions = Splitter.on(',').split(defaultRegions); this.defaultRegion = defaultRegion;
this.regions = Splitter.on(',').split(regions); this.regions = regions;
} }
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) { public <R extends HttpRequest> R bindToRequest(R request, Object input) {
input = input == null ? Iterables.get(defaultRegions, 0) : input; input = input == null ? defaultRegion : input;
checkArgument(input instanceof String, "this binder is only valid for Region!"); checkArgument(input instanceof String, "this binder is only valid for Region!");
String constraint = (String) input; String constraint = (String) input;
String value = null; String value = null;
if (Iterables.contains(defaultRegions, constraint)) { if (defaultRegion.equals(constraint)) {
// nothing to bind as this is default. // nothing to bind as this is default.
return request; return request;
} else if (Iterables.contains(regions, constraint)) { } else if (regions.contains(constraint)) {
value = constraint; value = constraint;
} else {
if (constraint.equals(Region.EU_WEST_1)) {
value = "EU";
} else { } else {
logger.warn("region %s not in %s ", constraint, regions); logger.warn("region %s not in %s ", constraint, regions);
value = constraint; value = constraint;
} }
}
String payload = String String payload = String
.format( .format(
"<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>", "<CreateBucketConfiguration><LocationConstraint>%s</LocationConstraint></CreateBucketConfiguration>",

View File

@ -23,7 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;

View File

@ -19,7 +19,7 @@
package org.jclouds.aws.sqs.config; package org.jclouds.aws.sqs.config;
import org.jclouds.aws.config.AWSFormSigningRestClientModule; import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.aws.sqs.SQSAsyncClient; import org.jclouds.aws.sqs.SQSAsyncClient;
import org.jclouds.aws.sqs.SQSClient; import org.jclouds.aws.sqs.SQSClient;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
@ -32,7 +32,7 @@ import org.jclouds.rest.ConfiguresRestClient;
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class SQSRestClientModule extends AWSFormSigningRestClientModule<SQSClient, SQSAsyncClient> { public class SQSRestClientModule extends FormSigningRestClientModule<SQSClient, SQSAsyncClient> {
public SQSRestClientModule() { public SQSRestClientModule() {
super(SQSClient.class, SQSAsyncClient.class); super(SQSClient.class, SQSAsyncClient.class);

View File

@ -34,7 +34,8 @@ import com.google.common.collect.ImmutableBiMap;
/** /**
* *
* @see <a href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryListQueues.html" * @see <a href=
* "http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryListQueues.html"
* /> * />
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -49,7 +50,7 @@ public class QueueHandler extends ParseSax.HandlerWithResult<Queue> {
@Inject @Inject
QueueHandler(Provider<UriBuilder> uriBuilderProvider, @Region Map<String, URI> regionMap) { QueueHandler(Provider<UriBuilder> uriBuilderProvider, @Region Map<String, URI> regionMap) {
this.uriBuilderProvider = uriBuilderProvider; this.uriBuilderProvider = uriBuilderProvider;
this.regionBiMap = ImmutableBiMap.<String, URI> builder().putAll(regionMap).build(); this.regionBiMap = ImmutableBiMap.<String, URI> copyOf(regionMap);
} }
public Queue getResult() { public Queue getResult() {

View File

@ -38,7 +38,6 @@ public class ProvidersInPropertiesTest {
public void testSupportedComputeServiceProviders() { public void testSupportedComputeServiceProviders() {
Iterable<String> providers = ComputeServiceUtils.getSupportedProviders(); Iterable<String> providers = ComputeServiceUtils.getSupportedProviders();
assert !Iterables.contains(providers, "sqs") : providers; assert !Iterables.contains(providers, "sqs") : providers;
assert !Iterables.contains(providers, "elb") : providers;
assert !Iterables.contains(providers, "s3") : providers; assert !Iterables.contains(providers, "s3") : providers;
assert !Iterables.contains(providers, "walrus") : providers; assert !Iterables.contains(providers, "walrus") : providers;
assert !Iterables.contains(providers, "googlestorage") : providers; assert !Iterables.contains(providers, "googlestorage") : providers;
@ -51,7 +50,6 @@ public class ProvidersInPropertiesTest {
public void testSupportedProviders() { public void testSupportedProviders() {
Iterable<String> providers = Providers.getSupportedProviders(); Iterable<String> providers = Providers.getSupportedProviders();
assert Iterables.contains(providers, "sqs") : providers; assert Iterables.contains(providers, "sqs") : providers;
assert Iterables.contains(providers, "elb") : providers;
assert Iterables.contains(providers, "s3") : providers; assert Iterables.contains(providers, "s3") : providers;
assert Iterables.contains(providers, "walrus") : providers; assert Iterables.contains(providers, "walrus") : providers;
assert Iterables.contains(providers, "googlestorage") : providers; assert Iterables.contains(providers, "googlestorage") : providers;
@ -64,7 +62,6 @@ public class ProvidersInPropertiesTest {
public void testSupportedBlobStoreProviders() { public void testSupportedBlobStoreProviders() {
Iterable<String> providers = BlobStoreUtils.getSupportedProviders(); Iterable<String> providers = BlobStoreUtils.getSupportedProviders();
assert !Iterables.contains(providers, "sqs") : providers; assert !Iterables.contains(providers, "sqs") : providers;
assert !Iterables.contains(providers, "elb") : providers;
assert Iterables.contains(providers, "s3") : providers; assert Iterables.contains(providers, "s3") : providers;
assert Iterables.contains(providers, "walrus") : providers; assert Iterables.contains(providers, "walrus") : providers;
assert Iterables.contains(providers, "googlestorage") : providers; assert Iterables.contains(providers, "googlestorage") : providers;

View File

@ -36,11 +36,11 @@ import com.google.common.collect.ImmutableMap;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(sequential = true, groups = { "unit" }) @Test(sequential = true, groups = { "unit" })
public class AWSRestClientModuleTest { public class AWSWithZonesFormSigningRestClientModuleTest {
@Test @Test
public void testDefaultRegionWhenThereIsAMatch() { public void testDefaultRegionWhenThereIsAMatch() {
AWSRestClientModule<EC2Client, EC2AsyncClient> module = new AWSRestClientModule<EC2Client, EC2AsyncClient>( AWSRestClientModule<EC2Client, EC2AsyncClient> module = new WithZonesFormSigningRestClientModule<EC2Client, EC2AsyncClient>(
EC2Client.class, EC2AsyncClient.class); EC2Client.class, EC2AsyncClient.class);
URI currentEndpoint = URI.create("http://region1"); URI currentEndpoint = URI.create("http://region1");
@ -51,7 +51,7 @@ public class AWSRestClientModuleTest {
@Test @Test
public void testDefaultRegionWhenThereIsNoMatch() { public void testDefaultRegionWhenThereIsNoMatch() {
AWSRestClientModule<EC2Client, EC2AsyncClient> module = new AWSRestClientModule<EC2Client, EC2AsyncClient>( AWSRestClientModule<EC2Client, EC2AsyncClient> module = new WithZonesFormSigningRestClientModule<EC2Client, EC2AsyncClient>(
EC2Client.class, EC2AsyncClient.class); EC2Client.class, EC2AsyncClient.class);
URI currentEndpoint = URI.create("http://region3"); URI currentEndpoint = URI.create("http://region3");

View File

@ -26,11 +26,7 @@ import java.net.URI;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.config.EC2RestClientModule; import org.jclouds.aws.ec2.config.EC2RestClientModule;
import org.jclouds.aws.ec2.domain.AvailabilityZone; import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.aws.filters.FormSigner; import org.jclouds.aws.filters.FormSigner;
@ -45,7 +41,6 @@ import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Module; import com.google.inject.Module;
/** /**
@ -58,24 +53,34 @@ public abstract class BaseEC2AsyncClientTest<T> extends RestClientTest<T> {
protected static class StubEC2RestClientModule extends EC2RestClientModule { protected static class StubEC2RestClientModule extends EC2RestClientModule {
@Override @Override
protected String provideTimeStamp(final DateService dateService, protected String provideTimeStamp(DateService dateService, int expiration) {
@Named(Constants.PROPERTY_SESSION_INTERVAL) final int expiration) {
return "2009-11-08T15:54:08.897Z"; return "2009-11-08T15:54:08.897Z";
} }
protected void bindRegionsToProvider() {
bindRegionsToProvider(Regions.class);
}
static class Regions implements javax.inject.Provider<Map<String, URI>> {
@Override @Override
protected Map<String, URI> provideRegions(Injector client) { public Map<String, URI> get() {
return ImmutableMap.<String, URI> of(Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), return ImmutableMap.<String, URI> of(Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"),
Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1,
URI.create("https://ec2.us-west-1.amazonaws.com")); URI.create("https://ec2.us-west-1.amazonaws.com"));
} }
}
protected void bindZonesToProvider() {
bindZonesToProvider(Zones.class);
}
static class Zones implements javax.inject.Provider<Map<String, String>> {
@Override @Override
protected Map<String, String> provideAvailabilityZoneToRegions(EC2Client client, public Map<String, String> get() {
@org.jclouds.location.Region Map<String, URI> regions) {
return ImmutableMap.<String, String> of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1); return ImmutableMap.<String, String> of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1);
} }
} }
}
protected FormSigner filter; protected FormSigner filter;

View File

@ -28,6 +28,7 @@ import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.location.Zone;
import org.testng.annotations.BeforeTest; import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -65,6 +66,7 @@ public class BaseEC2HandlerTest extends BaseHandlerTest {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Singleton @Singleton
@Provides @Provides
@Zone
Map<String, String> provideAvailabilityZoneRegionMap() { Map<String, String> provideAvailabilityZoneRegionMap() {
return ImmutableMap.<String, String> of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1); return ImmutableMap.<String, String> of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1);
} }

View File

@ -1,118 +0,0 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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 static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Properties;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.aws.elb.config.ELBRestClientModule;
import org.jclouds.aws.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.date.DateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
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 RestClientTest<ELBAsyncClient> {
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,
"Version=2009-11-25&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);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<ELBAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ELBAsyncClient>>() {
};
}
@RequiresHttp
@ConfiguresRestClient
private static final class TestELBRestClientModule extends ELBRestClientModule {
@Override
protected void configure() {
super.configure();
}
@Override
protected String provideTimeStamp(final DateService dateService,
@Named(Constants.PROPERTY_SESSION_INTERVAL) int expiration) {
return "2009-11-08T15:54:08.897Z";
}
}
@Override
protected Module createModule() {
return new TestELBRestClientModule();
}
@Override
public RestContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("elb", "identity", "credential",
new Properties());
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), FormSigner.class);
}
}

View File

@ -57,6 +57,12 @@ public class ParseAWSErrorFromXmlContentTest {
"<Error><Code>Monster.NotFound</Code></Error>", ResourceNotFoundException.class); "<Error><Code>Monster.NotFound</Code></Error>", ResourceNotFoundException.class);
} }
@Test
public void test400WithLoadBalancerNotFoundSetsResourceNotFoundException() {
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "",
"<Error><Code>LoadBalancerNotFound</Code></Error>", ResourceNotFoundException.class);
}
@Test @Test
public void test400WithUnsupportedCodeMakesUnsupportedOperationException() { public void test400WithUnsupportedCodeMakesUnsupportedOperationException() {
assertCodeMakes("POST", URI.create("https://ec2.us-west-1.amazonaws.com/"), 400, "", assertCodeMakes("POST", URI.create("https://ec2.us-west-1.amazonaws.com/"), 400, "",

View File

@ -26,6 +26,7 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.util.Throwables2; import org.jclouds.util.Throwables2;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -58,4 +59,9 @@ public class RetryOnTimeOutExceptionSupplier<T> implements Supplier<T> {
return null; return null;
} }
@Override
public String toString() {
return "RetryOnTimeOutExceptionSupplier(" + delegate + ")";
}
} }

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.location;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
* Related to a Zone-scoped resource.
*
* @author Adrian Cole
*
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Qualifier
public @interface Zone {
}

View File

@ -17,7 +17,7 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.functions; package org.jclouds.location.functions;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -25,7 +25,7 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.location.Region; import org.jclouds.location.Zone;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -34,19 +34,16 @@ import com.google.common.base.Function;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class AvailabilityZoneToEndpoint implements Function<Object, URI> { public class ZoneToEndpoint implements Function<Object, URI> {
private final Map<String, String> availabilityZoneToRegion; private final Map<String, URI> zoneToEndpoint;
private final Map<String, URI> regionToEndpoint;
@Inject @Inject
public AvailabilityZoneToEndpoint(@Region Map<String, URI> regionToEndpoint, public ZoneToEndpoint(@Zone Map<String, URI> zoneToEndpoint) {
Map<String, String> availabilityZoneToRegion) { this.zoneToEndpoint = zoneToEndpoint;
this.regionToEndpoint = regionToEndpoint;
this.availabilityZoneToRegion = availabilityZoneToRegion;
} }
public URI apply(Object from) { public URI apply(Object from) {
return regionToEndpoint.get(availabilityZoneToRegion.get(from)); return zoneToEndpoint.get(from);
} }
} }

View File

@ -0,0 +1,28 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.location.reference;
/**
*
* @author Adrian Cole
*/
public interface LocationConstants {
public static final String PROPERTY_REGIONS = "jclouds.location.regions";
}

View File

@ -41,21 +41,16 @@ import com.google.common.collect.Iterables;
*/ */
@Singleton @Singleton
public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> { public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
@Singleton
public static final class IsRegionAndIdEqualsOrIsZoneParentIdEquals implements Predicate<Location> {
private final String region; private final String region;
private final Supplier<Set<? extends Location>> locationsSupplier;
@Inject @Inject
FirstZoneOrRegionMatchingRegionId(@Region String region, @Memoized Supplier<Set<? extends Location>> locationsSupplier) { IsRegionAndIdEqualsOrIsZoneParentIdEquals(@Region String region) {
this.region = checkNotNull(region, "region"); this.region = checkNotNull(region, "region");
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
} }
@Override
@Singleton
public Location get() {
try {
Location toReturn = Iterables.find(locationsSupplier.get(), new Predicate<Location>() {
@Override @Override
public boolean apply(Location input) { public boolean apply(Location input) {
switch (input.getScope()) { switch (input.getScope()) {
@ -68,10 +63,31 @@ public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
} }
} }
}); @Override
public String toString() {
return "isRegionAndIdEqualsOrIsZoneParentIdEquals(" + region + ")";
}
}
private final IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher;
private final Supplier<Set<? extends Location>> locationsSupplier;
@Inject
FirstZoneOrRegionMatchingRegionId(IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher,
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
this.matcher = checkNotNull(matcher, "matcher");
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
}
@Override
@Singleton
public Location get() {
Set<? extends Location> locations = locationsSupplier.get();
try {
Location toReturn = Iterables.find(locations, matcher);
return toReturn.getScope() == LocationScope.REGION ? toReturn : toReturn.getParent(); return toReturn.getScope() == LocationScope.REGION ? toReturn : toReturn.getParent();
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
throw new IllegalStateException(String.format("region: %s not found in %s", region, locationsSupplier)); throw new IllegalStateException(String.format("region %s not found in %s", matcher, locations));
} }
} }
} }

View File

@ -42,25 +42,33 @@ import com.google.common.base.Supplier;
*/ */
@Singleton @Singleton
public class OnlyLocationOrFirstZone implements Supplier<Location> { public class OnlyLocationOrFirstZone implements Supplier<Location> {
@Singleton
public static final class IsZone implements Predicate<Location> {
@Override
public boolean apply(Location input) {
return input.getScope() == LocationScope.ZONE;
}
@Override
public String toString() {
return "isZone()";
}
}
private final Supplier<Set<? extends Location>> locationsSupplier; private final Supplier<Set<? extends Location>> locationsSupplier;
private final IsZone isZone;
@Inject @Inject
OnlyLocationOrFirstZone(@Memoized Supplier<Set<? extends Location>> locationsSupplier) { OnlyLocationOrFirstZone(@Memoized Supplier<Set<? extends Location>> locationsSupplier, IsZone isZone) {
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplierSupplier"); this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplierSupplier");
this.isZone = checkNotNull(isZone, "isZone");
} }
@Override @Override
public Location get() { public Location get() {
if (locationsSupplier.get().size() == 1) if (locationsSupplier.get().size() == 1)
return getOnlyElement(locationsSupplier.get()); return getOnlyElement(locationsSupplier.get());
return find(locationsSupplier.get(), new Predicate<Location>() { return find(locationsSupplier.get(), isZone);
@Override
public boolean apply(Location input) {
return input.getScope() == LocationScope.ZONE;
}
});
} }
} }

View File

@ -17,8 +17,9 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.aws.ec2.compute.suppliers; package org.jclouds.location.suppliers;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Maps.uniqueIndex; import static com.google.common.collect.Maps.uniqueIndex;
import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.collect.Sets.newLinkedHashSet;
@ -32,6 +33,7 @@ import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl; import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
import org.jclouds.location.Zone;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -42,21 +44,21 @@ import com.google.common.collect.ImmutableMap;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class EC2LocationSupplier implements Supplier<Set<? extends Location>> { public class ZoneToRegionToProvider implements Supplier<Set<? extends Location>> {
private final Map<String, String> availabilityZoneToRegionMap; private final Map<String, String> zoneToRegion;
private final String providerName; private final String providerName;
@Inject @Inject
EC2LocationSupplier(Map<String, String> availabilityZoneToRegionMap, @Provider String providerName) { ZoneToRegionToProvider(@Zone Map<String, String> zoneToRegion, @Provider String providerName) {
this.availabilityZoneToRegionMap = availabilityZoneToRegionMap; this.zoneToRegion = checkNotNull(zoneToRegion, "zoneToRegion");
this.providerName = providerName; this.providerName = checkNotNull(providerName, "providerName");
} }
@Override @Override
public Set<? extends Location> get() { public Set<? extends Location> get() {
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
Set<Location> locations = newLinkedHashSet(); Set<Location> locations = newLinkedHashSet();
for (String region : newLinkedHashSet(availabilityZoneToRegionMap.values())) { for (String region : newLinkedHashSet(zoneToRegion.values())) {
locations.add(new LocationImpl(LocationScope.REGION, region, region, ec2)); locations.add(new LocationImpl(LocationScope.REGION, region, region, ec2));
} }
ImmutableMap<String, Location> idToLocation = uniqueIndex(locations, new Function<Location, String>() { ImmutableMap<String, Location> idToLocation = uniqueIndex(locations, new Function<Location, String>() {
@ -65,9 +67,8 @@ public class EC2LocationSupplier implements Supplier<Set<? extends Location>> {
return from.getId(); return from.getId();
} }
}); });
for (String zone : availabilityZoneToRegionMap.keySet()) { for (String zone : zoneToRegion.keySet()) {
locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, idToLocation.get(availabilityZoneToRegionMap locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, idToLocation.get(zoneToRegion.get(zone))));
.get(zone))));
} }
return locations; return locations;
} }

View File

@ -48,7 +48,7 @@ public class RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements
private final Supplier<T> delegate; private final Supplier<T> delegate;
public RetryOnTimeOutButNotOnAuthorizationExceptionSupplier( public RetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
final AtomicReference<AuthorizationException> authException, long seconds, final Supplier<T> delegate) { final AtomicReference<AuthorizationException> authException, final long seconds, final Supplier<T> delegate) {
this.delegate = Suppliers.<T> memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<T>(new Supplier<T>() { this.delegate = Suppliers.<T> memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<T>(new Supplier<T>() {
public T get() { public T get() {
if (authException.get() != null) if (authException.get() != null)
@ -65,6 +65,11 @@ public class RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements
} }
} }
@Override
public String toString() {
return "memoizeWithExpiration(" + delegate + ", seconds=" + seconds + ")";
}
}), seconds, TimeUnit.SECONDS); }), seconds, TimeUnit.SECONDS);
} }
@ -73,4 +78,9 @@ public class RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements
return delegate.get(); return delegate.get();
} }
@Override
public String toString() {
return "RetryOnTimeOutButNotOnAuthorizationExceptionSupplier(" + delegate + ")";
}
} }

View File

@ -41,8 +41,8 @@ simpledb.propertiesbuilder=org.jclouds.simpledb.SimpleDBPropertiesBuilder
aws-simpledb.contextbuilder=org.jclouds.simpledb.SimpleDBContextBuilder aws-simpledb.contextbuilder=org.jclouds.simpledb.SimpleDBContextBuilder
aws-simpledb.propertiesbuilder=org.jclouds.aws.simpledb.SimpleDBPropertiesBuilder aws-simpledb.propertiesbuilder=org.jclouds.aws.simpledb.SimpleDBPropertiesBuilder
elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder elb.contextbuilder=org.jclouds.elb.ELBContextBuilder
elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder elb.propertiesbuilder=org.jclouds.elb.ELBPropertiesBuilder
cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder

View File

@ -40,6 +40,14 @@ import com.google.inject.ImplementedBy;
@ImplementedBy(BaseLoadBalancerService.class) @ImplementedBy(BaseLoadBalancerService.class)
public interface LoadBalancerService { public interface LoadBalancerService {
/**
* The list locations command returns all the valid locations for load balancers. A location has
* a scope, which is typically region or zone. A region is a general area, like eu-west, where a
* zone is similar to a datacenter. If a location has a parent, that implies it is within that
* location. For example a location can be a rack, whose parent is likely to be a zone.
*/
Set<? extends Location> listAssignableLocations();
/** /**
* @return a reference to the context that created this LoadBalancerService. * @return a reference to the context that created this LoadBalancerService.
*/ */
@ -75,6 +83,8 @@ public interface LoadBalancerService {
void destroyLoadBalancer(String id); void destroyLoadBalancer(String id);
@Beta @Beta
Set<String> listLoadBalancers(); Set<? extends LoadBalancerMetadata> listLoadBalancers();
LoadBalancerMetadata getLoadBalancerMetadata(String id);
} }

View File

@ -0,0 +1,67 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Location;
/**
* A means of specifying the interface between the {@link LoadBalancerService LoadBalancerServices}
* and a concrete compute cloud implementation, jclouds or otherwise.
*
* @author Adrian Cole
*
*/
public interface LoadBalancerServiceAdapter<B, L> {
/**
*
* @see LoadBalancerService#createLoadBalancerInLocation
*/
B createLoadBalancerInLocation(@Nullable Location location, String loadBalancerName, String protocol,
int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes);
/**
*
* @see LoadBalancerService#listAssignableLocations
*/
Iterable<L> listAssignableLocations();
/**
*
* @see LoadBalancerService#getLoadBalancerMetadata
*/
B getLoadBalancer(String id);
/**
*
* @see LoadBalancerService#destroyLoadBalancer
*/
void destroyLoadBalancer(String id);
/**
*
* @see LoadBalancerService#listLoadBalancers
*/
Iterable<B> listLoadBalancers();
}

View File

@ -0,0 +1,91 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.config;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public abstract class BaseLoadBalancerServiceContextModule extends AbstractModule {
protected AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
@Override
protected void configure() {
}
@Provides
@Singleton
protected Supplier<Map<String, ? extends Location>> provideLocationMap(
@Memoized Supplier<Set<? extends Location>> locations) {
return Suppliers.compose(new Function<Set<? extends Location>, Map<String, ? extends Location>>() {
@Override
public Map<String, ? extends Location> apply(Set<? extends Location> from) {
return Maps.uniqueIndex(from, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
}
}, locations);
}
@Provides
@Singleton
@Memoized
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Location>> locationSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
new Supplier<Set<? extends Location>>() {
@Override
public Set<? extends Location> get() {
return locationSupplier.get();
}
});
}
}

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.config;
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy;
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
/**
*
* @author Adrian Cole
*
*/
public abstract class BindLoadBalancerStrategiesByClass extends AbstractModule {
protected void configure() {
bindLoadBalanceNodesStrategy(defineLoadBalanceNodesStrategy());
bindListLoadBalancersStrategy(defineListLoadBalancersStrategy());
bindGetLoadBalancerMetadataStrategy(defineGetLoadBalancerMetadataStrategy());
bindDestroyLoadBalancerStrategy(defineDestroyLoadBalancerStrategy());
}
protected void bindLoadBalanceNodesStrategy(Class<? extends LoadBalanceNodesStrategy> clazz) {
bind(LoadBalanceNodesStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected void bindDestroyLoadBalancerStrategy(Class<? extends DestroyLoadBalancerStrategy> clazz) {
bind(DestroyLoadBalancerStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected void bindGetLoadBalancerMetadataStrategy(Class<? extends GetLoadBalancerMetadataStrategy> clazz) {
bind(GetLoadBalancerMetadataStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected void bindListLoadBalancersStrategy(Class<? extends ListLoadBalancersStrategy> clazz) {
bind(ListLoadBalancersStrategy.class).to(clazz).in(Scopes.SINGLETON);
}
protected abstract Class<? extends LoadBalanceNodesStrategy> defineLoadBalanceNodesStrategy();
protected abstract Class<? extends DestroyLoadBalancerStrategy> defineDestroyLoadBalancerStrategy();
protected abstract Class<? extends GetLoadBalancerMetadataStrategy> defineGetLoadBalancerMetadataStrategy();
protected abstract Class<? extends ListLoadBalancersStrategy> defineListLoadBalancersStrategy();
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.config;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import com.google.common.base.Supplier;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
/**
* @author Adrian Cole
*/
public abstract class BindLoadBalancerSuppliersByClass extends AbstractModule {
@Override
protected void configure() {
bindLocationSupplier(defineLocationSupplier());
bindDefaultLocationSupplier(defineDefaultLocationSupplier());
}
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return SupplierOfLocationSet.class;
}
@Singleton
static class SupplierOfLocationSet implements Supplier<Set<? extends Location>> {
private final Set<? extends Location> locations;
@Inject
SupplierOfLocationSet(Set<? extends Location> locations) {
this.locations = locations;
}
@Override
public Set<? extends Location> get() {
return locations;
}
}
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return OnlyLocationOrFirstZone.class;
}
protected void bindImageSupplier(Class<? extends Supplier<Set<? extends Image>>> clazz) {
bind(new TypeLiteral<Supplier<Set<? extends Image>>>() {
}).to(clazz).in(Scopes.SINGLETON);
}
protected void bindLocationSupplier(Class<? extends Supplier<Set<? extends Location>>> clazz) {
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
}).to(clazz).in(Scopes.SINGLETON);
}
protected void bindDefaultLocationSupplier(Class<? extends Supplier<Location>> clazz) {
bind(new TypeLiteral<Supplier<Location>>() {
}).to(clazz).in(Scopes.SINGLETON);
}
protected void bindHardwareSupplier(Class<? extends Supplier<Set<? extends Hardware>>> clazz) {
bind(new TypeLiteral<Supplier<Set<? extends Hardware>>>() {
}).to(clazz).in(Scopes.SINGLETON);
}
}

View File

@ -21,25 +21,34 @@ package org.jclouds.loadbalancer.internal;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.newLinkedHashSet;
import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
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.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.loadbalancer.LoadBalancerService; import org.jclouds.loadbalancer.LoadBalancerService;
import org.jclouds.loadbalancer.LoadBalancerServiceContext; import org.jclouds.loadbalancer.LoadBalancerServiceContext;
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.DestroyLoadBalancerStrategy; import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
import org.jclouds.loadbalancer.strategy.GetLoadBalancerMetadataStrategy;
import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy;
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy; import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.predicates.RetryablePredicate;
import com.google.common.collect.ImmutableSet; import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
@ -54,23 +63,36 @@ public class BaseLoadBalancerService implements LoadBalancerService {
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER) @Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final Supplier<Location> defaultLocationSupplier;
protected final LoadBalancerServiceContext context; protected final LoadBalancerServiceContext context;
protected final LoadBalanceNodesStrategy loadBalancerStrategy; protected final LoadBalanceNodesStrategy loadBalancerStrategy;
protected final GetLoadBalancerMetadataStrategy getLoadBalancerMetadataStrategy;
protected final DestroyLoadBalancerStrategy destroyLoadBalancerStrategy; protected final DestroyLoadBalancerStrategy destroyLoadBalancerStrategy;
// protected final ListLoadBalancersStrategy listLoadBalancersStrategy; protected final ListLoadBalancersStrategy listLoadBalancersStrategy;
protected final BackoffLimitedRetryHandler backoffLimitedRetryHandler; protected final Supplier<Set<? extends Location>> locations;
@Inject @Inject
protected BaseLoadBalancerService(LoadBalancerServiceContext context, LoadBalanceNodesStrategy loadBalancerStrategy, protected BaseLoadBalancerService(Supplier<Location> defaultLocationSupplier, LoadBalancerServiceContext context,
DestroyLoadBalancerStrategy destroyLoadBalancerStrategy, LoadBalanceNodesStrategy loadBalancerStrategy,
// ListLoadBalancersStrategy listLoadBalancersStrategy, GetLoadBalancerMetadataStrategy getLoadBalancerMetadataStrategy,
BackoffLimitedRetryHandler backoffLimitedRetryHandler) { DestroyLoadBalancerStrategy destroyLoadBalancerStrategy, ListLoadBalancersStrategy listLoadBalancersStrategy,
@Memoized Supplier<Set<? extends Location>> locations) {
this.defaultLocationSupplier = checkNotNull(defaultLocationSupplier, "defaultLocationSupplier");
this.context = checkNotNull(context, "context"); this.context = checkNotNull(context, "context");
this.loadBalancerStrategy = checkNotNull(loadBalancerStrategy, "loadBalancerStrategy"); this.loadBalancerStrategy = checkNotNull(loadBalancerStrategy, "loadBalancerStrategy");
this.getLoadBalancerMetadataStrategy = checkNotNull(getLoadBalancerMetadataStrategy,
"getLoadBalancerMetadataStrategy");
this.destroyLoadBalancerStrategy = checkNotNull(destroyLoadBalancerStrategy, "destroyLoadBalancerStrategy"); this.destroyLoadBalancerStrategy = checkNotNull(destroyLoadBalancerStrategy, "destroyLoadBalancerStrategy");
// this.listLoadBalancersStrategy = checkNotNull(listLoadBalancersStrategy, this.listLoadBalancersStrategy = checkNotNull(listLoadBalancersStrategy, "listLoadBalancersStrategy");
// "listLoadBalancersStrategy"); this.locations = checkNotNull(locations, "locations");
this.backoffLimitedRetryHandler = checkNotNull(backoffLimitedRetryHandler, "backoffLimitedRetryHandler"); }
/**
* {@inheritDoc}
*/
@Override
public Set<? extends Location> listAssignableLocations() {
return locations.get();
} }
/** /**
@ -82,18 +104,20 @@ public class BaseLoadBalancerService implements LoadBalancerService {
} }
@Override @Override
public LoadBalancerMetadata createLoadBalancerInLocation(Location location, String loadBalancerName, public LoadBalancerMetadata createLoadBalancerInLocation(@Nullable Location location, String loadBalancerName,
String protocol, int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) { String protocol, int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) {
if (location == null)
location = defaultLocationSupplier.get();
checkNotNull(loadBalancerName, "loadBalancerName"); checkNotNull(loadBalancerName, "loadBalancerName");
checkNotNull(protocol, "protocol"); checkNotNull(protocol, "protocol");
checkArgument(protocol.toUpperCase().equals("HTTP") || protocol.toUpperCase().equals("TCP"), checkArgument(protocol.toUpperCase().equals("HTTP") || protocol.toUpperCase().equals("TCP"),
"Acceptable values for protocol are HTTP or TCP"); "Acceptable values for protocol are HTTP or TCP");
logger.debug(">> creating load balancer (%s)", loadBalancerName); logger.debug(">> creating load balancer (%s)", loadBalancerName);
LoadBalancerMetadata lb = loadBalancerStrategy.execute(location, loadBalancerName, protocol, loadBalancerPort, LoadBalancerMetadata lb = loadBalancerStrategy.createLoadBalancerInLocation(location, loadBalancerName, protocol,
instancePort, nodes); loadBalancerPort, instancePort, nodes);
logger.debug("<< created load balancer (%s)", loadBalancerName, lb); logger.debug("<< created load balancer (%s)", loadBalancerName, lb);
return lb; return lb;
} }
@ -101,18 +125,48 @@ public class BaseLoadBalancerService implements LoadBalancerService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void destroyLoadBalancer(String loadBalancer) { public LoadBalancerMetadata getLoadBalancerMetadata(String id) {
checkNotNull(loadBalancer, "loadBalancer"); checkNotNull(id, "id");
logger.debug(">> destroying load balancer(%s)", loadBalancer); return getLoadBalancerMetadataStrategy.getLoadBalancer(id);
boolean successful = destroyLoadBalancerStrategy.execute(loadBalancer);
logger.debug("<< destroyed load balancer(%s) success(%s)", loadBalancer, successful);
} }
public Set<String> listLoadBalancers() { /**
return ImmutableSet.of(); * {@inheritDoc}
// TODO */
// Set<String> loadBalancerSet = listLoadBalancersStrategy.execute(); @Override
// return loadBalancerSet; public void destroyLoadBalancer(final String id) {
checkNotNull(id, "id");
logger.debug(">> destroying load balancer(%s)", id);
final AtomicReference<LoadBalancerMetadata> loadBalancer = new AtomicReference<LoadBalancerMetadata>();
RetryablePredicate<String> tester = new RetryablePredicate<String>(new Predicate<String>() {
@Override
public boolean apply(String input) {
try {
LoadBalancerMetadata md = destroyLoadBalancerStrategy.destroyLoadBalancer(id);
if (md != null)
loadBalancer.set(md);
return true;
} catch (IllegalStateException e) {
logger.warn("<< illegal state destroying load balancer(%s)", id);
return false;
}
}
}, 3000, 1000, TimeUnit.MILLISECONDS);// TODO make timeouts class like ComputeServiceconstants
boolean successful = tester.apply(id) && loadBalancer.get() == null; // TODO add load
// balancerTerminated
// retryable predicate
// (load balancer.get() == null ||
// load balancerTerminated.apply(load balancer.get()));
logger.debug("<< destroyed load balancer(%s) success(%s)", id, successful);
}
public Set<? extends LoadBalancerMetadata> listLoadBalancers() {
logger.debug(">> listing load balancers");
LinkedHashSet<LoadBalancerMetadata> set = newLinkedHashSet(listLoadBalancersStrategy.listLoadBalancers());
logger.debug("<< list(%d)", set.size());
return set;
} }
} }

View File

@ -19,6 +19,8 @@
package org.jclouds.loadbalancer.strategy; package org.jclouds.loadbalancer.strategy;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
/** /**
@ -29,6 +31,6 @@ import com.google.common.annotations.Beta;
@Beta @Beta
public interface DestroyLoadBalancerStrategy { public interface DestroyLoadBalancerStrategy {
boolean execute(String loadBalancer); LoadBalancerMetadata destroyLoadBalancer(String id);
} }

View File

@ -0,0 +1,33 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.loadbalancer.strategy;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
/**
* returns all details associated to the node below.
*
* @author Adrian Cole
*/
public interface GetLoadBalancerMetadataStrategy {
LoadBalancerMetadata getLoadBalancer(String id);
}

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
* *
* ==================================================================== * ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -17,9 +17,9 @@
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.compute.strategy; package org.jclouds.loadbalancer.strategy;
import java.util.Set; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
@ -31,6 +31,6 @@ import com.google.common.annotations.Beta;
@Beta @Beta
public interface ListLoadBalancersStrategy { public interface ListLoadBalancersStrategy {
Set<String> execute(); Iterable<? extends LoadBalancerMetadata> listLoadBalancers();
} }

View File

@ -54,7 +54,7 @@ public interface LoadBalanceNodesStrategy {
* @see org.jclouds.compute.ComputeService * @see org.jclouds.compute.ComputeService
*/ */
@Beta @Beta
LoadBalancerMetadata execute(Location location, String name, String protocol, int loadBalancerPort, LoadBalancerMetadata createLoadBalancerInLocation(Location location, String name, String protocol, int loadBalancerPort,
int instancePort, Iterable<? extends NodeMetadata> nodes); int instancePort, Iterable<? extends NodeMetadata> nodes);
} }

View File

@ -87,8 +87,8 @@ public abstract class BaseLoadBalancerServiceLiveTest {
credential = System.getProperty("test." + provider + ".credential"); credential = System.getProperty("test." + provider + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint"); endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion"); apiversion = System.getProperty("test." + provider + ".apiversion");
computeProvider = checkNotNull(System.getProperty("test." + provider + ".compute.provider"), "test." + provider
computeProvider = checkNotNull(System.getProperty("test.compute.provider"), "test.compute.provider"); + ".compute.provider");
computeIdentity = checkNotNull(System.getProperty("test." + computeProvider + ".identity"), "test." computeIdentity = checkNotNull(System.getProperty("test." + computeProvider + ".identity"), "test."
+ computeProvider + ".identity"); + computeProvider + ".identity");
computeCredential = System.getProperty("test." + computeProvider + ".credential"); computeCredential = System.getProperty("test." + computeProvider + ".credential");
@ -164,7 +164,7 @@ public abstract class BaseLoadBalancerServiceLiveTest {
abstract protected Module getSshModule(); abstract protected Module getSshModule();
@BeforeGroups(groups = { "integration", "live" }) @BeforeGroups(groups = { "integration", "live" }, dependsOnMethods = "setupClient")
public void createNodes() throws RunNodesException { public void createNodes() throws RunNodesException {
try { try {
nodes = computeContext.getComputeService().runNodesWithTag(tag, 2); nodes = computeContext.getComputeService().runNodesWithTag(tag, 2);
@ -195,7 +195,7 @@ public abstract class BaseLoadBalancerServiceLiveTest {
@AfterTest @AfterTest
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException { protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (loadbalancer != null) { if (loadbalancer != null) {
context.getLoadBalancerService().destroyLoadBalancer(tag); context.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId());
} }
if (nodes != null) { if (nodes != null) {
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));

View File

@ -25,7 +25,7 @@ import static org.jclouds.aws.domain.Region.EU_WEST_1;
import static org.jclouds.aws.domain.Region.US_EAST_1; import static org.jclouds.aws.domain.Region.US_EAST_1;
import static org.jclouds.aws.domain.Region.US_WEST_1; import static org.jclouds.aws.domain.Region.US_WEST_1;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_REGIONS; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;

View File

@ -21,6 +21,7 @@ package org.jclouds.aws.simpledb;
import static org.jclouds.aws.simpledb.SimpleDBPropertiesBuilder.DEFAULT_REGIONS; import static org.jclouds.aws.simpledb.SimpleDBPropertiesBuilder.DEFAULT_REGIONS;
import org.jclouds.simpledb.SimpleDBClientLiveTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
/** /**
@ -28,11 +29,10 @@ import org.testng.annotations.Test;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "live", sequential = true, testName = "aws.SimpleDBClientLiveTest") @Test(groups = "live", sequential = true, testName = "AWSSimpleDBClientLiveTest")
public class SimpleDBClientLiveTest extends org.jclouds.simpledb.SimpleDBClientLiveTest { public class AWSSimpleDBClientLiveTest extends SimpleDBClientLiveTest {
public SimpleDBClientLiveTest(){ public AWSSimpleDBClientLiveTest(){
provider = "aws-simpledb"; provider = "aws-simpledb";
} }
@Test @Test
void testListDomainsInRegion() throws InterruptedException { void testListDomainsInRegion() throws InterruptedException {