Merge pull request #277 from richardcloudsoft/cloudstack-lb

CloudStack LoadBalancer fixes
This commit is contained in:
Adrian Cole 2011-12-21 17:20:07 -08:00
commit 55c182484f
5 changed files with 76 additions and 12 deletions

View File

@ -80,9 +80,9 @@ public interface LoadBalancerAsyncClient {
*/ */
@GET @GET
@QueryParams(keys = "command", values = "createLoadBalancerRule") @QueryParams(keys = "command", values = "createLoadBalancerRule")
@SelectJson("loadbalancerrule") @SelectJson("jobid")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<LoadBalancerRule> createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId, ListenableFuture<Long> createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId,
@QueryParam("algorithm") Algorithm algorithm, @QueryParam("name") String name, @QueryParam("algorithm") Algorithm algorithm, @QueryParam("name") String name,
@QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort); @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort);
@ -145,7 +145,7 @@ public interface LoadBalancerAsyncClient {
*/ */
@GET @GET
@QueryParams(keys = "command", values = "listLoadBalancerRuleInstances") @QueryParams(keys = "command", values = "listLoadBalancerRuleInstances")
@SelectJson("loadbalancerrule") @SelectJson("loadbalancerruleinstance")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<VirtualMachine>> listVirtualMachinesAssignedToLoadBalancerRule(@QueryParam("id") long id); ListenableFuture<Set<VirtualMachine>> listVirtualMachinesAssignedToLoadBalancerRule(@QueryParam("id") long id);

View File

@ -74,7 +74,7 @@ public interface LoadBalancerClient {
* balanced from * balanced from
* @return newly created rule * @return newly created rule
*/ */
LoadBalancerRule createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name, Long createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name,
int privatePort, int publicPort); int privatePort, int publicPort);
/** /**

View File

@ -34,6 +34,7 @@ import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.AsyncJob.Builder; import org.jclouds.cloudstack.domain.AsyncJob.Builder;
import org.jclouds.cloudstack.domain.AsyncJobError; import org.jclouds.cloudstack.domain.AsyncJobError;
import org.jclouds.cloudstack.domain.IPForwardingRule; import org.jclouds.cloudstack.domain.IPForwardingRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PortForwardingRule;
import org.jclouds.cloudstack.domain.PublicIPAddress; import org.jclouds.cloudstack.domain.PublicIPAddress;
@ -71,7 +72,8 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
.put("ipforwardingrule", IPForwardingRule.class) .put("ipforwardingrule", IPForwardingRule.class)
.put("network", Network.class) .put("network", Network.class)
.put("ipaddress", PublicIPAddress.class) .put("ipaddress", PublicIPAddress.class)
.put("virtualmachine", VirtualMachine.class).build(); .put("virtualmachine", VirtualMachine.class)
.put("loadbalancer", LoadBalancerRule.class).build();
private final Json json; private final Json json;
@Inject @Inject

View File

@ -20,6 +20,7 @@ package org.jclouds.cloudstack.predicates;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkService; import org.jclouds.cloudstack.domain.NetworkService;
@ -27,6 +28,8 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import javax.annotation.Nullable;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -75,6 +78,21 @@ public class NetworkPredicates {
} }
} }
public static enum IsVirtualNetwork implements Predicate<Network> {
INSTANCE;
@Override
public boolean apply(Network arg0) {
boolean network = isVirtualNetwork.apply(checkNotNull(arg0, "network").getGuestIPType());
return network;
}
@Override
public String toString() {
return isVirtualNetwork.toString();
}
}
public static class NetworkServiceNamed implements Predicate<NetworkService> { public static class NetworkServiceNamed implements Predicate<NetworkService> {
private final String name; private final String name;
@ -93,6 +111,24 @@ public class NetworkPredicates {
} }
} }
public static class GuestIPTypeIs implements Predicate<GuestIPType> {
private final GuestIPType guestIPType;
public GuestIPTypeIs(GuestIPType guestIPType) {
this.guestIPType = guestIPType;
}
@Override
public boolean apply(@Nullable GuestIPType guestIPType) {
return guestIPType == this.guestIPType;
}
@Override
public String toString() {
return "guestIPTypeIs(" + guestIPType + ')';
}
}
public static class CapabilitiesInclude implements Predicate<NetworkService> { public static class CapabilitiesInclude implements Predicate<NetworkService> {
private final String capability; private final String capability;
@ -119,6 +155,8 @@ public class NetworkPredicates {
public static Predicate<NetworkService> isLoadBalancerService = new NetworkServiceNamed("Lb"); public static Predicate<NetworkService> isLoadBalancerService = new NetworkServiceNamed("Lb");
public static Predicate<GuestIPType> isVirtualNetwork = new GuestIPTypeIs(GuestIPType.VIRTUAL);
/** /**
* *
* @return true, if the network supports static NAT. * @return true, if the network supports static NAT.
@ -143,6 +181,14 @@ public class NetworkPredicates {
return HasLoadBalancerService.INSTANCE; return HasLoadBalancerService.INSTANCE;
} }
/**
*
* @return true, if the network is a virtual network.
*/
public static Predicate<Network> isVirtualNetwork() {
return IsVirtualNetwork.INSTANCE;
}
/** /**
* *
* @return always returns true. * @return always returns true.

View File

@ -28,6 +28,9 @@ import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.google.common.base.Predicates;
import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.JobResult;
import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.LoadBalancerRule;
import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.Algorithm;
import org.jclouds.cloudstack.domain.LoadBalancerRule.State; import org.jclouds.cloudstack.domain.LoadBalancerRule.State;
@ -67,7 +70,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
TimeUnit.SECONDS); TimeUnit.SECONDS);
prefix += "rule"; prefix += "rule";
try { try {
network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.hasLoadBalancerService()); network = find(client.getNetworkClient().listNetworks(), Predicates.and(NetworkPredicates.hasLoadBalancerService(), NetworkPredicates.isVirtualNetwork()));
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
networksDisabled = true; networksDisabled = true;
} }
@ -89,13 +92,18 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
if (networksDisabled) if (networksDisabled)
return; return;
int attempts = 0; int attempts = 0;
while (rule == null && attempts < 50) { while (rule == null && attempts < 10) {
ip = reuseOrAssociate.apply(network); ip = reuseOrAssociate.apply(network);
try { try {
rule = client.getLoadBalancerClient().createLoadBalancerRuleForPublicIP(ip.getId(), Algorithm.LEASTCONN, Long jobId = client.getLoadBalancerClient().createLoadBalancerRuleForPublicIP(ip.getId(), Algorithm.LEASTCONN,
prefix, 22, 22); prefix, 22, 22);
assertTrue(jobComplete.apply(jobId));
AsyncJob<LoadBalancerRule> asyncJob = client.getAsyncJobClient().getAsyncJob(jobId);
LoadBalancerRule result = asyncJob.getResult();
rule = result;
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
// very likely an ip conflict, so retry; // very likely an ip conflict, so retry;
attempts++;
} }
} }
assertNotNull(rule, "Failed to get a load balancer rule after "+attempts+" attempts"); assertNotNull(rule, "Failed to get a load balancer rule after "+attempts+" attempts");
@ -114,10 +122,18 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest {
public void testAssignToLoadBalancerRule() throws Exception { public void testAssignToLoadBalancerRule() throws Exception {
if (networksDisabled) if (networksDisabled)
return; return;
assertTrue(jobComplete.apply(client.getLoadBalancerClient().assignVirtualMachinesToLoadBalancerRule(rule.getId(), long jobId = client.getLoadBalancerClient().assignVirtualMachinesToLoadBalancerRule(rule.getId(),
vm.getId()))); vm.getId());
assertEquals(client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()).size(), 1); assertTrue(jobComplete.apply(jobId));
AsyncJob<JobResult> result = client.getAsyncJobClient().getAsyncJob(jobId);
assertTrue(result.hasSucceed());
Set<VirtualMachine> machines = client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId());
assertEquals(machines.size(), 1);
assertTrue(loadBalancerRuleActive.apply(rule), rule.toString()); assertTrue(loadBalancerRuleActive.apply(rule), rule.toString());
}
@Test(dependsOnMethods = "testAssignToLoadBalancerRule")
public void testCanSshInThroughNewLoadBalancerRule() throws Exception {
loopAndCheckSSH(); loopAndCheckSSH();
} }