diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java index cc368ecbe2..db05a7e2d7 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerAsyncClient.java @@ -80,9 +80,9 @@ public interface LoadBalancerAsyncClient { */ @GET @QueryParams(keys = "command", values = "createLoadBalancerRule") - @SelectJson("loadbalancerrule") + @SelectJson("jobid") @Consumes(MediaType.APPLICATION_JSON) - ListenableFuture createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId, + ListenableFuture createLoadBalancerRuleForPublicIP(@QueryParam("publicipid") long publicIPId, @QueryParam("algorithm") Algorithm algorithm, @QueryParam("name") String name, @QueryParam("privateport") int privatePort, @QueryParam("publicport") int publicPort); @@ -145,7 +145,7 @@ public interface LoadBalancerAsyncClient { */ @GET @QueryParams(keys = "command", values = "listLoadBalancerRuleInstances") - @SelectJson("loadbalancerrule") + @SelectJson("loadbalancerruleinstance") @Consumes(MediaType.APPLICATION_JSON) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> listVirtualMachinesAssignedToLoadBalancerRule(@QueryParam("id") long id); diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java index a998af6a4d..8e6da5e82c 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/LoadBalancerClient.java @@ -74,7 +74,7 @@ public interface LoadBalancerClient { * balanced from * @return newly created rule */ - LoadBalancerRule createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name, + Long createLoadBalancerRuleForPublicIP(long publicIPId, Algorithm algorithm, String name, int privatePort, int publicPort); /** diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseTypedAsyncJob.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseTypedAsyncJob.java index 3dd64f1c98..0f29a07ee9 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseTypedAsyncJob.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ParseTypedAsyncJob.java @@ -34,6 +34,7 @@ import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob.Builder; import org.jclouds.cloudstack.domain.AsyncJobError; import org.jclouds.cloudstack.domain.IPForwardingRule; +import org.jclouds.cloudstack.domain.LoadBalancerRule; import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.PortForwardingRule; import org.jclouds.cloudstack.domain.PublicIPAddress; @@ -71,7 +72,8 @@ public class ParseTypedAsyncJob implements Function { + 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 { private final String name; @@ -93,6 +111,24 @@ public class NetworkPredicates { } } + public static class GuestIPTypeIs implements Predicate { + 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 { private final String capability; @@ -119,6 +155,8 @@ public class NetworkPredicates { public static Predicate isLoadBalancerService = new NetworkServiceNamed("Lb"); + public static Predicate isVirtualNetwork = new GuestIPTypeIs(GuestIPType.VIRTUAL); + /** * * @return true, if the network supports static NAT. @@ -136,13 +174,21 @@ public class NetworkPredicates { } /** - * + * * @return true, if the network supports load balancing. */ public static Predicate hasLoadBalancerService() { return HasLoadBalancerService.INSTANCE; } + /** + * + * @return true, if the network is a virtual network. + */ + public static Predicate isVirtualNetwork() { + return IsVirtualNetwork.INSTANCE; + } + /** * * @return always returns true. diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java index 2c1e315aea..e9298e2f65 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/LoadBalancerClientLiveTest.java @@ -28,6 +28,9 @@ import java.util.NoSuchElementException; import java.util.Set; 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.Algorithm; import org.jclouds.cloudstack.domain.LoadBalancerRule.State; @@ -67,7 +70,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest { TimeUnit.SECONDS); prefix += "rule"; try { - network = find(client.getNetworkClient().listNetworks(), NetworkPredicates.hasLoadBalancerService()); + network = find(client.getNetworkClient().listNetworks(), Predicates.and(NetworkPredicates.hasLoadBalancerService(), NetworkPredicates.isVirtualNetwork())); } catch (NoSuchElementException e) { networksDisabled = true; } @@ -89,13 +92,18 @@ public class LoadBalancerClientLiveTest extends BaseCloudStackClientLiveTest { if (networksDisabled) return; int attempts = 0; - while (rule == null && attempts < 50) { + while (rule == null && attempts < 10) { ip = reuseOrAssociate.apply(network); try { - rule = client.getLoadBalancerClient().createLoadBalancerRuleForPublicIP(ip.getId(), Algorithm.LEASTCONN, + Long jobId = client.getLoadBalancerClient().createLoadBalancerRuleForPublicIP(ip.getId(), Algorithm.LEASTCONN, prefix, 22, 22); + assertTrue(jobComplete.apply(jobId)); + AsyncJob asyncJob = client.getAsyncJobClient().getAsyncJob(jobId); + LoadBalancerRule result = asyncJob.getResult(); + rule = result; } catch (IllegalStateException e) { // very likely an ip conflict, so retry; + 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 { if (networksDisabled) return; - assertTrue(jobComplete.apply(client.getLoadBalancerClient().assignVirtualMachinesToLoadBalancerRule(rule.getId(), - vm.getId()))); - assertEquals(client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()).size(), 1); + long jobId = client.getLoadBalancerClient().assignVirtualMachinesToLoadBalancerRule(rule.getId(), + vm.getId()); + assertTrue(jobComplete.apply(jobId)); + AsyncJob result = client.getAsyncJobClient().getAsyncJob(jobId); + assertTrue(result.hasSucceed()); + Set machines = client.getLoadBalancerClient().listVirtualMachinesAssignedToLoadBalancerRule(rule.getId()); + assertEquals(machines.size(), 1); assertTrue(loadBalancerRuleActive.apply(rule), rule.toString()); + } + + @Test(dependsOnMethods = "testAssignToLoadBalancerRule") + public void testCanSshInThroughNewLoadBalancerRule() throws Exception { loopAndCheckSSH(); }