mirror of https://github.com/apache/jclouds.git
Load Balancer ComputeService API
This commit is contained in:
parent
d3690c44f2
commit
0d1d28a972
|
@ -18,8 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.util.Utils.checkNotEmpty;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -44,15 +47,19 @@ import org.jclouds.compute.domain.Size;
|
|||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.LoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
import org.jclouds.domain.Location;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
|
@ -72,6 +79,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
LoadBalancerStrategy loadBalancerStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||
|
@ -79,7 +87,7 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
Map<RegionAndName, KeyPair> credentialsMap, Map<RegionAndName, String> securityGroupMap) {
|
||||
super(context, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
templateBuilderProvider, templateOptionsProvider, utils, executor);
|
||||
loadBalancerStrategy, templateBuilderProvider, templateOptionsProvider, utils, executor);
|
||||
this.ec2Client = ec2Client;
|
||||
this.getRegionFromLocation = getRegionFromLocation;
|
||||
this.credentialsMap = credentialsMap;
|
||||
|
@ -128,6 +136,54 @@ public class EC2ComputeService extends BaseComputeService {
|
|||
deleteSecurityGroup(regionTag.getKey(), regionTag.getValue());
|
||||
}
|
||||
return deadOnes;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String loadBalanceNodesMatching(String loadBalancerName,
|
||||
String protocol, Integer loadBalancerPort, Integer instancePort,
|
||||
Predicate<NodeMetadata> filter)
|
||||
{
|
||||
checkNotNull(loadBalancerName, "loadBalancerName");
|
||||
checkNotNull(protocol, "protocol");
|
||||
checkArgument(protocol.toUpperCase().equals("HTTP")
|
||||
|| protocol.toUpperCase().equals("TCP"),
|
||||
"Acceptable values for protocol are HTTP or TCP");
|
||||
checkNotNull(loadBalancerPort, "loadBalancerPort");
|
||||
checkNotNull(instancePort, "instancePort");
|
||||
|
||||
Location location = null;
|
||||
Set<String> ids = new HashSet<String>();
|
||||
for (final NodeMetadata node : Iterables.filter(super
|
||||
.listNodesDetailsMatching(NodePredicates.all()), Predicates
|
||||
.and(filter, Predicates.not(NodePredicates.TERMINATED))))
|
||||
{
|
||||
ids.add(node.getId());
|
||||
location = node.getLocation();
|
||||
}
|
||||
logger.debug(">> creating load balancer (%s)", loadBalancerName);
|
||||
String dnsName = loadBalancerStrategy
|
||||
.execute(location, loadBalancerName, protocol,
|
||||
loadBalancerPort, instancePort, ids);
|
||||
logger.debug("<< created load balancer (%s) DNS (%s)",
|
||||
loadBalancerName, dnsName);
|
||||
return dnsName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void deleteLoadBalancer(String loadBalancerName,
|
||||
Predicate<NodeMetadata> filter)
|
||||
{
|
||||
|
||||
Location location = Iterables.filter(
|
||||
super.listNodesDetailsMatching(NodePredicates.all()),
|
||||
Predicates.and(filter, Predicates
|
||||
.not(NodePredicates.TERMINATED))).iterator().next()
|
||||
.getLocation();
|
||||
ec2Client.getElasticLoadBalancerServices().deleteLoadBalancer(
|
||||
getRegionFromLocation.apply(location), loadBalancerName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.jclouds.aws.ec2.compute.functions.RunningInstanceToNodeMetadata;
|
|||
import org.jclouds.aws.ec2.compute.internal.EC2TemplateBuilderImpl;
|
||||
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.compute.strategy.EC2DestroyNodeStrategy;
|
||||
import org.jclouds.aws.ec2.compute.strategy.EC2LoadBalancerStrategy;
|
||||
import org.jclouds.aws.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.aws.ec2.config.EC2ContextModule;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
|
@ -79,6 +80,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.LoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.concurrent.ConcurrentUtils;
|
||||
|
@ -129,6 +131,7 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
bind(GetNodeMetadataStrategy.class).to(EC2GetNodeMetadataStrategy.class);
|
||||
bind(RebootNodeStrategy.class).to(EC2RebootNodeStrategy.class);
|
||||
bind(DestroyNodeStrategy.class).to(EC2DestroyNodeStrategy.class);
|
||||
bind(LoadBalancerStrategy.class).to(EC2LoadBalancerStrategy.class);
|
||||
bind(new TypeLiteral<Function<RunningInstance, Map<String, String>>>() {
|
||||
}).annotatedWith(Jsr330.named("volumeMapping")).to(RunningInstanceToStorageMappingUnix.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -77,15 +79,31 @@ public class EC2LoadBalancerStrategy implements LoadBalancerStrategy
|
|||
dnsName = elbClient.createLoadBalancer(region, name, protocol,
|
||||
loadBalancerPort, instancePort, availabilityZone);
|
||||
|
||||
List<String> instanceIdlist = new ArrayList<String>(instanceIds);
|
||||
String[] instanceIdArray = new String[instanceIdlist.size()];
|
||||
for(int i=0; i<instanceIdlist.size(); i++)
|
||||
{
|
||||
instanceIdArray[i] = instanceIdlist.get(i);
|
||||
}
|
||||
|
||||
Set<String> registeredInstanceIds = elbClient
|
||||
.registerInstancesWithLoadBalancer(region, name,
|
||||
(String[]) instanceIds.toArray());
|
||||
instanceIdArray);
|
||||
|
||||
// deregister instances
|
||||
boolean changed = registeredInstanceIds.removeAll(instanceIds);
|
||||
if (changed)
|
||||
{
|
||||
List<String> list = new ArrayList<String>(registeredInstanceIds);
|
||||
instanceIdArray = new String[list.size()];
|
||||
for(int i=0; i<list.size(); i++)
|
||||
{
|
||||
instanceIdArray[i] = list.get(i);
|
||||
}
|
||||
if(instanceIdArray.length>0)
|
||||
elbClient.deregisterInstancesWithLoadBalancer(region, name,
|
||||
(String[]) registeredInstanceIds.toArray());
|
||||
instanceIdArray);
|
||||
}
|
||||
|
||||
return dnsName;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public interface ElasticLoadBalancerAsyncClient
|
|||
*/
|
||||
@POST
|
||||
@Path("/")
|
||||
@FormParams(keys = ACTION, values = "DeregisterInstancesWithLoadBalancer")
|
||||
@FormParams(keys = ACTION, values = "DeregisterInstancesFromLoadBalancer")
|
||||
ListenableFuture<Void> deregisterInstancesWithLoadBalancer(
|
||||
@EndpointParam(parser = ELBRegionToEndpoint.class) @Nullable String region,
|
||||
@FormParam("LoadBalancerName") String name,
|
||||
|
|
|
@ -30,6 +30,8 @@ public class RegisterInstancesWithLoadBalancerResponseHandler extends
|
|||
{
|
||||
if(qName.equals("InstanceId"))
|
||||
instanceIds.add(currentText.toString().trim());
|
||||
|
||||
currentText = new StringBuilder();
|
||||
}
|
||||
@Override
|
||||
public Set<String> getResult()
|
||||
|
|
|
@ -19,20 +19,26 @@
|
|||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.compute.options.EC2TemplateOptions;
|
||||
import org.jclouds.aws.ec2.domain.ElasticLoadBalancer;
|
||||
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.domain.SecurityGroup;
|
||||
import org.jclouds.aws.ec2.services.ElasticLoadBalancerClient;
|
||||
import org.jclouds.aws.ec2.services.InstanceClient;
|
||||
import org.jclouds.aws.ec2.services.KeyPairClient;
|
||||
import org.jclouds.aws.ec2.services.SecurityGroupClient;
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.domain.Credentials;
|
||||
|
@ -173,6 +179,39 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadBalanceNodesMatching() throws Exception{
|
||||
|
||||
ElasticLoadBalancerClient elbClient = EC2Client.class.cast(
|
||||
context.getProviderSpecificContext().getApi())
|
||||
.getElasticLoadBalancerServices();
|
||||
|
||||
String tag = "jcloudsElbTest";
|
||||
Template template = client.templateBuilder().build();
|
||||
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 2,
|
||||
template);
|
||||
Set<String> instanceIds = new HashSet<String>();
|
||||
for (NodeMetadata node : nodes)
|
||||
{
|
||||
instanceIds.add(node.getId());
|
||||
}
|
||||
|
||||
// create load balancer
|
||||
String dnsName = client.loadBalanceNodesMatching(tag, "HTTP", 80, 80,
|
||||
NodePredicates.withTag(tag));
|
||||
assertNotNull(dnsName);
|
||||
Set<ElasticLoadBalancer> elbs = elbClient.describeLoadBalancers(
|
||||
Region.US_EAST_1, tag);
|
||||
assertNotNull(elbs);
|
||||
ElasticLoadBalancer elb = elbs.iterator().next();
|
||||
assertEquals(elb.getInstanceIds(), instanceIds);
|
||||
|
||||
elbClient.deleteLoadBalancer(Region.US_EAST_1, tag);
|
||||
//finaly destroy nodes
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
|
||||
}
|
||||
|
||||
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||
.describeInstancesInRegion(null, id)));
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
*
|
||||
* 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.xml;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.aws.ec2.domain.ElasticLoadBalancer;
|
||||
import org.jclouds.http.functions.ParseSax;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Tests behavior of {@code DescribeLoadBalancersResponseHandler}
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ec2.RegisterInstancesWithLoadBalancerResponseHandlerTest")
|
||||
public class RegisterInstancesWithLoadBalancerResponseHandlerTest extends
|
||||
BaseEC2HandlerTest
|
||||
{
|
||||
|
||||
public void testParse()
|
||||
{
|
||||
InputStream is = getClass().getResourceAsStream(
|
||||
"/ec2/register_instances_with_loadbalancer.xml");
|
||||
|
||||
Set<String> instanceIds = Sets.newHashSet();
|
||||
instanceIds.add("i-6055fa09");
|
||||
instanceIds.add("i-9055fa55");
|
||||
|
||||
|
||||
Set<String> result = parseXML(is);
|
||||
|
||||
assertEquals(result, instanceIds);
|
||||
}
|
||||
|
||||
private Set<String> parseXML(InputStream is)
|
||||
{
|
||||
RegisterInstancesWithLoadBalancerResponseHandler handler = injector
|
||||
.getInstance(RegisterInstancesWithLoadBalancerResponseHandler.class);
|
||||
Set<String> result = factory.create(handler).parse(is);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<RegisterInstancesWithLoadBalancerResult>
|
||||
<Instances>
|
||||
<member>
|
||||
<InstanceId>i-6055fa09</InstanceId>
|
||||
<InstanceId>i-9055fa55</InstanceId>
|
||||
</member>
|
||||
</Instances>
|
||||
</RegisterInstancesWithLoadBalancerResult>
|
|
@ -214,4 +214,32 @@ public interface ComputeService {
|
|||
Predicate<NodeMetadata> filter, byte[] runScript, RunScriptOptions options)
|
||||
throws RunScriptOnNodesException;
|
||||
|
||||
/**
|
||||
* @param loadBalancerName
|
||||
* Load balancer name
|
||||
* @param protocol
|
||||
* LoadBalancer transport protocol to use for routing - TCP or
|
||||
* HTTP. This property cannot be modified for the life of the
|
||||
* LoadBalancer.
|
||||
* @param loadBalancerPort
|
||||
* The external TCP port of the LoadBalancer. Valid LoadBalancer
|
||||
* ports are - 80, 443 and 1024 through 65535. This property
|
||||
* cannot be modified for the life of the LoadBalancer.
|
||||
* @param instancePort
|
||||
* The InstancePort data type is simple type of type: integer. It
|
||||
* is the TCP port on which the server on the instance is
|
||||
* listening. Valid instance ports are one (1) through 65535.
|
||||
* This property cannot be modified for the life of the
|
||||
* LoadBalancer.
|
||||
* @param filter
|
||||
* Predicate-based filter to define on which nodes the script is
|
||||
* to be executed
|
||||
* @return DNS Name of the load balancer
|
||||
*/
|
||||
String loadBalanceNodesMatching(String loadBalancerName, String protocol,
|
||||
Integer loadBalancerPort, Integer instancePort,
|
||||
Predicate<NodeMetadata> filter);
|
||||
|
||||
void deleteLoadBalancer(String loadBalancerName, Predicate<NodeMetadata> filter);
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
|
|||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.LoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||
import org.jclouds.compute.util.ComputeUtils;
|
||||
|
@ -95,6 +96,7 @@ public class BaseComputeService implements ComputeService {
|
|||
protected final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy;
|
||||
protected final RebootNodeStrategy rebootNodeStrategy;
|
||||
protected final DestroyNodeStrategy destroyNodeStrategy;
|
||||
protected final LoadBalancerStrategy loadBalancerStrategy;
|
||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
protected final Provider<TemplateOptions> templateOptionsProvider;
|
||||
protected final ComputeUtils utils;
|
||||
|
@ -107,7 +109,7 @@ public class BaseComputeService implements ComputeService {
|
|||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
LoadBalancerStrategy loadBalancerStrategy, Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider, ComputeUtils utils,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
|
@ -121,6 +123,7 @@ public class BaseComputeService implements ComputeService {
|
|||
"runNodesAndAddToSetStrategy");
|
||||
this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy");
|
||||
this.destroyNodeStrategy = checkNotNull(destroyNodeStrategy, "destroyNodeStrategy");
|
||||
this.loadBalancerStrategy = checkNotNull(loadBalancerStrategy, "loadBalancerStrategy");
|
||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider,
|
||||
"templateBuilderProvider");
|
||||
this.templateOptionsProvider = checkNotNull(templateOptionsProvider,
|
||||
|
@ -381,6 +384,10 @@ public class BaseComputeService implements ComputeService {
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
private Iterable<? extends NodeMetadata> verifyParametersAndListNodes(
|
||||
Predicate<NodeMetadata> filter, byte[] runScript, final RunScriptOptions options) {
|
||||
checkNotNull(filter, "Filter must be provided");
|
||||
|
@ -416,6 +423,28 @@ public class BaseComputeService implements ComputeService {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String loadBalanceNodesMatching(String loadBalancerName,
|
||||
String protocol, Integer loadBalancerPort, Integer instancePort,
|
||||
Predicate<NodeMetadata> filter)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void deleteLoadBalancer(String loadBalancerName,
|
||||
Predicate<NodeMetadata> filter)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private Iterable<? extends NodeMetadata> detailsOnAllNodes() {
|
||||
return listNodesStrategy.listDetailsOnNodesMatching(NodePredicates.all());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue