Issue 852: cleaned remaining elb methods

This commit is contained in:
Adrian Cole 2012-07-06 20:23:09 -07:00
parent 25e68b328c
commit 578c9e93f9
11 changed files with 218 additions and 104 deletions

View File

@ -77,7 +77,7 @@ public class ELBApiMetadata extends BaseRestApiMetadata {
.name("Amazon Elastic Load Balancing Api")
.identityName("Access Key ID")
.credentialName("Secret Access Key")
.version(ELBAsyncClient.VERSION)
.version("2012-06-01")
.defaultProperties(ELBApiMetadata.defaultProperties())
.defaultEndpoint("https://elasticloadbalancing.us-east-1.amazonaws.com")
.documentation(URI.create("http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference"))

View File

@ -18,33 +18,22 @@
*/
package org.jclouds.elb;
import static org.jclouds.aws.reference.FormParameters.ACTION;
import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.elb.features.InstanceAsyncClient;
import org.jclouds.elb.features.LoadBalancerAsyncClient;
import org.jclouds.elb.features.PolicyAsyncClient;
import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
/**
@ -53,7 +42,7 @@ import com.google.inject.Provides;
*
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference/">ELB
* documentation</a>
* @author Lili Nader
* @author Adrian Cole
*/
@Beta
@RequestFilters(FormSigner.class)
@ -66,55 +55,26 @@ public interface ELBAsyncClient {
@Provides
@Region
Set<String> getConfiguredRegions();
/**
* Provides asynchronous access to LoadBalancer features.
*/
@Delegate
LoadBalancerAsyncClient getLoadBalancerClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
LoadBalancerAsyncClient getLoadBalancerClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides asynchronous access to Policy features.
*/
@Delegate
PolicyAsyncClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
PolicyAsyncClient getPolicyClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides asynchronous access to Instance features.
*/
@Delegate
InstanceAsyncClient getInstanceClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/// old stuff
public static final String VERSION = "2012-06-01";
// TODO: there are a lot of missing methods
/**
* @see ELBClient#createLoadBalancerInRegion
*/
@POST
@Path("/")
@XMLResponseParser(CreateLoadBalancerResponseHandler.class)
@FormParams(keys = ACTION, values = "CreateLoadBalancer")
@Beta
// TODO:The way this handles arguments needs to be refactored. it needs to deal with collections
// of listeners.
ListenableFuture<String> createLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name, @FormParam("Listeners.member.1.Protocol") String protocol,
@FormParam("Listeners.member.1.LoadBalancerPort") int loadBalancerPort,
@FormParam("Listeners.member.1.InstancePort") int instancePort,
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) String... availabilityZones);
/**
* @see ELBClient#deleteLoadBalancerInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteLoadBalancer")
ListenableFuture<Void> deleteLoadBalancerInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("LoadBalancerName") String name);
InstanceAsyncClient getInstanceClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
}

View File

@ -39,10 +39,10 @@ import com.google.inject.Provides;
* Provides access to EC2 Elastic Load Balancer via their REST API.
* <p/>
*
* @author Lili Nader
* @author Adrian Cole
* @see ELBAsyncClient
*/
@Beta
// see ELBAsyncClient
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ELBClient {
/**
@ -52,55 +52,26 @@ public interface ELBClient {
@Provides
@Region
Set<String> getConfiguredRegions();
/**
* Provides synchronous access to LoadBalancer features.
*/
@Delegate
LoadBalancerClient getLoadBalancerClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
LoadBalancerClient getLoadBalancerClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides synchronous access to Policy features.
*/
@Delegate
PolicyClient getPolicyClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
PolicyClient getPolicyClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/**
* Provides synchronous access to Instance features.
*/
@Delegate
InstanceClient getInstanceClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
/// old stuff
/**
* Creates a load balancer
*
* @param name
* Name of the load balancer
* @param loadBalancerPort
* Port for the load balancer to listen on
* @param instancePort
* Port to forward the request to
* @param availabilityZones
* load balancer availability zones
* @return dns the DNS name for the load balancer
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/DeveloperGuide/"
*/
@Beta
// see ELBAsyncClient
String createLoadBalancerInRegion(@Nullable String region, String name, String protocol, int loadBalancerPort,
int instancePort, String... availabilityZones);
/**
* Delete load balancer
*
* @param name
* Name of the load balancer
* @return
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/2009-05-15/DeveloperGuide/"
*/
void deleteLoadBalancerInRegion(@Nullable String region, String name);
InstanceClient getInstanceClientForRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
}

View File

@ -18,7 +18,7 @@
*/
package org.jclouds.elb.binders;
import static org.jclouds.aws.util.AWSUtils.indexStringArrayToFormValuesWithStringFormat;
import static org.jclouds.aws.util.AWSUtils.indexIterableToFormValuesWithPrefix;
import javax.inject.Singleton;
@ -26,7 +26,7 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the String [] to form parameters named with InstanceId.index
* Binds the Iterable<String> to form parameters named with AvailabilityZones.member.N
*
* @author Adrian Cole
*/
@ -34,7 +34,7 @@ import org.jclouds.rest.Binder;
public class BindAvailabilityZonesToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return indexStringArrayToFormValuesWithStringFormat(request, "AvailabilityZones.member.%s", input);
return indexIterableToFormValuesWithPrefix(request, "AvailabilityZones.member", input);
}
}

View File

@ -0,0 +1,66 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.elb.domain.Listener;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.utils.ModifyRequest;
import com.google.common.collect.ImmutableMultimap;
/**
* Binds the listeners request to the http request
*
* @see <a
* href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference/API_CreateLoadBalancer.html"
* >doc</a>
*
* @author Adrian Cole
*/
public class BindListenersToFormParams implements org.jclouds.rest.Binder {
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
Iterable<Listener> listeners = (Iterable<Listener>) checkNotNull(input, "listeners must be set!");
ImmutableMultimap.Builder<String, String> formParameters = ImmutableMultimap.builder();
int listenerIndex = 1;
for (Listener listener : listeners) {
formParameters.put("Listeners.member." + listenerIndex + ".LoadBalancerPort", listener.getPort() + "");
formParameters.put("Listeners.member." + listenerIndex + ".InstancePort", listener.getInstancePort() + "");
formParameters.put("Listeners.member." + listenerIndex + ".Protocol", listener.getProtocol() + "");
formParameters.put("Listeners.member." + listenerIndex + ".InstanceProtocol", listener.getInstanceProtocol()
+ "");
if (listener.getSSLCertificateId().isPresent())
formParameters.put("Listeners.member." + listenerIndex + ".SSLCertificateId", listener
.getSSLCertificateId().get() + "");
listenerIndex++;
}
return ModifyRequest.putFormParams(request, formParameters.build());
}
}

View File

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

View File

@ -0,0 +1,40 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.elb.binders;
import static org.jclouds.aws.util.AWSUtils.indexIterableToFormValuesWithPrefix;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the Iterable<String> to form parameters named with Subnets.member.N
*
* @author Adrian Cole
*/
@Singleton
public class BindSubnetsToIndexedFormParams implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
return indexIterableToFormValuesWithPrefix(request, "Subnets.member", input);
}
}

View File

@ -18,16 +18,25 @@
*/
package org.jclouds.elb.features;
import static org.jclouds.aws.reference.FormParameters.ACTION;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams;
import org.jclouds.elb.binders.BindListenersToFormParams;
import org.jclouds.elb.binders.BindSecurityGroupsToIndexedFormParams;
import org.jclouds.elb.binders.BindSubnetsToIndexedFormParams;
import org.jclouds.elb.domain.Listener;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.options.ListLoadBalancersOptions;
import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler;
import org.jclouds.elb.xml.DescribeLoadBalancersResultHandler;
import org.jclouds.elb.xml.LoadBalancerHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -41,14 +50,37 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to Amazon ELB via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference" >doc</a>
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference"
* >doc</a>
* @see LoadBalancerClient
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@VirtualHost
public interface LoadBalancerAsyncClient {
/**
* @see LoadBalancerClient#createLoadBalancerListeningInAvailabilityZones()
*/
@POST
@Path("/")
@XMLResponseParser(CreateLoadBalancerResponseHandler.class)
@FormParams(keys = ACTION, values = "CreateLoadBalancer")
ListenableFuture<String> createLoadBalancerListeningInAvailabilityZones(@FormParam("LoadBalancerName") String name,
@BinderParam(BindListenersToFormParams.class) Iterable<Listener> listeners,
@BinderParam(BindAvailabilityZonesToIndexedFormParams.class) Iterable<String> availabilityZones);
/**
* @see LoadBalancerClient#createLoadBalancerListeningInSubnetsAssignedToSecurityGroups()
*/
@POST
@Path("/")
@XMLResponseParser(CreateLoadBalancerResponseHandler.class)
@FormParams(keys = ACTION, values = "CreateLoadBalancer")
ListenableFuture<String> createLoadBalancerListeningInSubnetsAssignedToSecurityGroups(
@FormParam("LoadBalancerName") String name,
@BinderParam(BindSubnetsToIndexedFormParams.class) Iterable<Listener> subnetIds,
@BinderParam(BindSecurityGroupsToIndexedFormParams.class) Iterable<String> securityGroupIds);
/**
* @see LoadBalancerClient#get()
*/
@ -58,7 +90,7 @@ public interface LoadBalancerAsyncClient {
@FormParams(keys = "Action", values = "DescribeLoadBalancers")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<LoadBalancer> get(@FormParam("LoadBalancerNames.member.1") String name);
/**
* @see LoadBalancerClient#list()
*/
@ -77,4 +109,11 @@ public interface LoadBalancerAsyncClient {
@FormParams(keys = "Action", values = "DescribeLoadBalancers")
ListenableFuture<PaginatedSet<LoadBalancer>> list(ListLoadBalancersOptions options);
/**
* @see LoadBalancerClient#delete()
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteLoadBalancer")
ListenableFuture<Void> delete(@FormParam("LoadBalancerName") String name);
}

View File

@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.collect.PaginatedSet;
import org.jclouds.concurrent.Timeout;
import org.jclouds.elb.domain.Listener;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.elb.options.ListLoadBalancersOptions;
import org.jclouds.javax.annotation.Nullable;
@ -30,12 +31,20 @@ import org.jclouds.javax.annotation.Nullable;
* Provides access to Amazon ELB via the Query API
* <p/>
*
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference" />
* @see <a href="http://docs.amazonwebservices.com/ElasticLoadBalancing/latest/APIReference" >doc</a>
* @see LoadBalancerAsyncClient
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface LoadBalancerClient {
String createLoadBalancerListeningInAvailabilityZones(String name, Iterable<Listener> listeners,
Iterable<String> availabilityZones);
String createLoadBalancerListeningInSubnetsAssignedToSecurityGroups(String name, Iterable<Listener> subnetIds,
Iterable<String> securityGroupIds);
/**
* Retrieves information about the specified loadBalancer.
*
@ -47,8 +56,8 @@ public interface LoadBalancerClient {
LoadBalancer get(String name);
/**
* Returns detailed configuration information for the specified LoadBalancers. If there are none, the action returns an
* empty list.
* Returns detailed configuration information for the specified LoadBalancers. If there are none,
* the action returns an empty list.
*
* <br/>
* You can paginate the results using the {@link ListLoadBalancersOptions parameter}
@ -67,4 +76,29 @@ public interface LoadBalancerClient {
*/
PaginatedSet<LoadBalancer> list();
/**
* Deletes the specified LoadBalancer.
*
* <p/>
* If attempting to recreate the LoadBalancer, the client must reconfigure all the settings. The
* DNS name associated with a deleted LoadBalancer will no longer be usable. Once deleted, the
* name and associated DNS record of the LoadBalancer no longer exist and traffic sent to any of
* its IP addresses will no longer be delivered to client instances. The client will not receive
* the same DNS name even if a new LoadBalancer with same LoadBalancerName is created.
*
* <p/>
* To successfully call this API, the client must provide the same account credentials as were
* used to create the LoadBalancer.
*
* <h4>Note</h4>
*
* By design, if the LoadBalancer does not exist or has already been deleted, DeleteLoadBalancer
* still succeeds.
*
*
* @param name
* Name of the load balancer
*/
void delete(String name);
}

View File

@ -57,7 +57,7 @@ public class ELBDestroyLoadBalancerStrategy implements DestroyLoadBalancerStrate
String[] parts = parseHandle(id);
String region = parts[0];
String instanceId = parts[1];
elbClient.deleteLoadBalancerInRegion(region, instanceId);
elbClient.getLoadBalancerClientForRegion(region).delete(instanceId);
return getLoadBalancer.getLoadBalancer(id);
}
}

View File

@ -35,6 +35,8 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Location;
import org.jclouds.elb.ELBClient;
import org.jclouds.elb.domain.Listener;
import org.jclouds.elb.domain.Protocol;
import org.jclouds.elb.domain.regionscoped.LoadBalancerInRegion;
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
@ -79,8 +81,10 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
logger.debug(">> creating loadBalancer(%s)", name);
try {
String dnsName = client.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort,
availabilityZones.toArray(new String[] {}));
String dnsName = client.getLoadBalancerClientForRegion(region).createLoadBalancerListeningInAvailabilityZones(
name,
ImmutableSet.of(Listener.builder().port(loadBalancerPort).instancePort(instancePort)
.protocol(Protocol.valueOf(protocol)).build()), availabilityZones);
logger.debug("<< created loadBalancer(%s) dnsName(%s)", name, dnsName);
} catch (IllegalStateException e) {
logger.debug("<< reusing loadBalancer(%s)", name);