You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2017/12/20 07:28:56 UTC

jclouds-labs git commit: network and image tests / correct zones configuration

Repository: jclouds-labs
Updated Branches:
  refs/heads/master 889b34b96 -> 9c74d22bb


network and image tests / correct zones configuration


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/9c74d22b
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/9c74d22b
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/9c74d22b

Branch: refs/heads/master
Commit: 9c74d22bb8723df1b31113265fef504272c66b23
Parents: 889b34b
Author: Boris Trishkin <bo...@itaas.dimensiondata.com>
Authored: Tue Dec 19 14:34:36 2017 +0000
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Dec 20 08:24:28 2017 +0100

----------------------------------------------------------------------
 .../features/InfrastructureApi.java             |   7 +-
 .../cloudcontrol/features/NetworkApi.java       |  26 ++-
 .../features/InfrastructureApiLiveTest.java     |  11 +-
 .../features/InfrastructureApiMockTest.java     |  40 ++--
 .../features/NetworkApiLiveTest.java            | 120 ++++++++++-
 .../features/NetworkApiMockTest.java            | 207 +++++++++++++++----
 .../features/ServerImageApiLiveTest.java        |   7 +
 .../features/ServerImageApiMockTest.java        |   4 +-
 .../cloudcontrol/features/TagApiMockTest.java   |   4 +-
 ...aseDimensionDataCloudControlApiLiveTest.java |  27 ++-
 .../BaseDimensionDataCloudControlMockTest.java  |  15 +-
 11 files changed, 384 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
index eafef2e..a2debef 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApi.java
@@ -47,6 +47,7 @@ import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
+import java.util.Set;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
@@ -75,7 +76,7 @@ public interface InfrastructureApi {
    @Path("/operatingSystem")
    @ResponseParser(ParseOperatingSystems.class)
    @Fallback(Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404.class)
-   PaginatedCollection<OperatingSystem> listOperatingSystems(@QueryParam("datacenterId") String datacenterId,
+   PaginatedCollection<OperatingSystem> listOperatingSystems(@QueryParam("datacenterId") Set<String> datacenterId,
          PaginationOptions options);
 
    @Named("infrastructure:operatingSystem")
@@ -84,7 +85,7 @@ public interface InfrastructureApi {
    @Transform(ParseOperatingSystems.ToPagedIterable.class)
    @ResponseParser(ParseOperatingSystems.class)
    @Fallback(Fallbacks.EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<OperatingSystem> listOperatingSystems(@QueryParam("datacenterId") String datacenterId);
+   PagedIterable<OperatingSystem> listOperatingSystems(@QueryParam("datacenterId") Set<String> datacenterId);
 
    final class ParseDatacenters extends ParseJson<Datacenters> {
 
@@ -138,7 +139,7 @@ public interface InfrastructureApi {
                @Override
                public IterableWithMarker<OperatingSystem> apply(Object input) {
                   PaginationOptions paginationOptions = PaginationOptions.class.cast(input);
-                  return api.getInfrastructureApi().listOperatingSystems(arg.get().toString(), paginationOptions);
+                  return api.getInfrastructureApi().listOperatingSystems((Set<String>) arg.get(), paginationOptions);
                }
             };
          }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
index 129fa99..2a4629b 100644
--- a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
+++ b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApi.java
@@ -37,7 +37,6 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.PaginatedCollection;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Placement;
 import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock;
 import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlocks;
-import org.jclouds.dimensiondata.cloudcontrol.domain.Response;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Vlans;
 import org.jclouds.dimensiondata.cloudcontrol.filters.OrganisationIdFilter;
@@ -165,7 +164,8 @@ public interface NetworkApi {
    @Path("/addPublicIpBlock")
    @Produces(MediaType.APPLICATION_JSON)
    @MapBinder(BindToJsonPayload.class)
-   Response addPublicIpBlock(@PayloadParam("networkDomainId") String networkDomainId);
+   @ResponseParser(ParsePublicIpBlockId.class)
+   String addPublicIpBlock(@PayloadParam("networkDomainId") String networkDomainId);
 
    @Named("networkDomain:listPublicIPv4AddressBlocks")
    @GET
@@ -203,7 +203,8 @@ public interface NetworkApi {
    @Produces(MediaType.APPLICATION_JSON)
    @MapBinder(BindToJsonPayload.class)
    @Fallback(Fallbacks.VoidOnNotFoundOr404.class)
-   Response createNatRule(@PayloadParam("networkDomainId") String networkDomainId,
+   @ResponseParser(ParseNatRuleId.class)
+   String createNatRule(@PayloadParam("networkDomainId") String networkDomainId,
          @PayloadParam("internalIp") String internalIp, @PayloadParam("externalIp") String externalIp);
 
    @Named("networkDomain:listNatRules")
@@ -483,5 +484,24 @@ public interface NetworkApi {
          super(json, "firewallRuleId");
       }
    }
+
+   @Singleton
+   final class ParsePublicIpBlockId extends ParseResponse {
+
+      @Inject
+      ParsePublicIpBlockId(Json json) {
+         super(json, "ipBlockId");
+      }
+   }
+
+   @Singleton
+   final class ParseNatRuleId extends ParseResponse {
+
+      @Inject
+      ParseNatRuleId(Json json) {
+         super(json, "natRuleId");
+      }
+   }
+
 }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiLiveTest.java
index 20f3b29..640ec8b 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiLiveTest.java
@@ -22,6 +22,9 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.testng.annotations.Test;
 
+import java.util.Set;
+import java.util.HashSet;
+
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
@@ -45,9 +48,11 @@ public class InfrastructureApiLiveTest extends BaseDimensionDataCloudControlApiL
 
    @Test
    public void testListOperatingSystems() {
-      FluentIterable<Datacenter> datacenters = getDatacenters();
-      FluentIterable<OperatingSystem> operatingSystems = api().listOperatingSystems(datacenters.first().get().id())
-            .concat();
+      Set<String> datacenterIds = new HashSet<String>();
+      for (Datacenter dc : getDatacenters()) {
+         datacenterIds.add(dc.id());
+      }
+      FluentIterable<OperatingSystem> operatingSystems = api().listOperatingSystems(datacenterIds).concat();
       assertNotNull(operatingSystems);
       assertTrue(!operatingSystems.isEmpty());
       for (OperatingSystem operatingSystem : operatingSystems) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiMockTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiMockTest.java
index c44f764..2658d91 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/InfrastructureApiMockTest.java
@@ -16,15 +16,14 @@
  */
 package org.jclouds.dimensiondata.cloudcontrol.features;
 
+import com.google.common.collect.Sets;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Datacenter;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseAccountAwareCloudControlMockTest;
 import org.jclouds.http.Uris;
-import org.jclouds.location.suppliers.ZoneIdsSupplier;
 import org.testng.annotations.Test;
 
 import javax.ws.rs.HttpMethod;
-import java.util.Set;
 
 import static com.google.common.collect.Iterables.size;
 import static org.testng.Assert.assertEquals;
@@ -43,7 +42,7 @@ public class InfrastructureApiMockTest extends BaseAccountAwareCloudControlMockT
       assertEquals(size(datacenters), 1); // Force the PagedIterable to advance
       assertEquals(server.getRequestCount(), 2);
 
-      assertSent(HttpMethod.GET, expectedListDatacentersUriBuilder().toString());
+      assertSent(HttpMethod.GET, addZonesToUriBuilder(expectedListDatacentersUriBuilder()).toString());
    }
 
    public void testListDatacentersWithPagination() throws Exception {
@@ -53,29 +52,32 @@ public class InfrastructureApiMockTest extends BaseAccountAwareCloudControlMockT
 
       consumeIterableAndAssertAdditionalPagesRequested(datacenters, 2, 1);
 
-      assertSent(HttpMethod.GET, expectedListDatacentersUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListDatacentersUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addZonesToUriBuilder(expectedListDatacentersUriBuilder()).toString());
+      assertSent(HttpMethod.GET, addZonesToUriBuilder(expectedListDatacentersWithPaginationUriBuilder(2)).toString());
    }
 
    public void testListDatacenters404() throws Exception {
       server.enqueue(response404());
       assertTrue(api.getInfrastructureApi().listDatacenters().concat().isEmpty());
-      assertSent(HttpMethod.GET, expectedListDatacentersUriBuilder().toString());
+      assertSent(HttpMethod.GET, addZonesToUriBuilder(expectedListDatacentersUriBuilder()).toString());
    }
 
    private Uris.UriBuilder expectedListDatacentersUriBuilder() {
       Uris.UriBuilder uriBuilder = Uris
             .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/infrastructure/datacenter");
-      Set<String> zones = ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
-      for (String zone : zones) {
-         uriBuilder.addQuery("id", zone);
-      }
-      return uriBuilder;
+      return addZonesToUriBuilder(uriBuilder);
+   }
+
+   private Uris.UriBuilder expectedListDatacentersWithPaginationUriBuilder(int pageNumber) {
+      Uris.UriBuilder uriBuilder = Uris
+            .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/infrastructure/datacenter");
+      return addZonesToUriBuilder(addPageNumberToUriBuilder(uriBuilder, pageNumber, true));
    }
 
    public void testListOperatingSystems() throws Exception {
       server.enqueue(jsonResponse("/operatingSystems.json"));
-      Iterable<OperatingSystem> operatingSystems = api.getInfrastructureApi().listOperatingSystems("NA9").concat();
+      Iterable<OperatingSystem> operatingSystems = api.getInfrastructureApi()
+            .listOperatingSystems(Sets.newHashSet("NA1", "NA9")).concat();
 
       assertEquals(size(operatingSystems), 33);
       assertEquals(server.getRequestCount(), 2);
@@ -86,26 +88,32 @@ public class InfrastructureApiMockTest extends BaseAccountAwareCloudControlMockT
    public void testListOperatingSystemsWithPagination() throws Exception {
       server.enqueue(jsonResponse("/operatingSystems-page1.json"));
       server.enqueue(jsonResponse("/operatingSystems-page2.json"));
-      Iterable<OperatingSystem> operatingSystems = api.getInfrastructureApi().listOperatingSystems("NA9").concat();
+      Iterable<OperatingSystem> operatingSystems = api.getInfrastructureApi()
+            .listOperatingSystems(Sets.newHashSet("NA1", "NA9")).concat();
 
       consumeIterableAndAssertAdditionalPagesRequested(operatingSystems, 33, 1);
 
       assertSent(HttpMethod.GET, expectedListOperatingSystemsUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListOperatingSystemsUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, expectedListOperatingSystemsWithPaginationUriBuilder(2).toString());
 
    }
 
    public void testListOperatingSystems404() throws Exception {
       server.enqueue(response404());
-      assertTrue(api.getInfrastructureApi().listOperatingSystems("NA9").concat().isEmpty());
+      assertTrue(api.getInfrastructureApi().listOperatingSystems(Sets.newHashSet("NA1", "NA9")).concat().isEmpty());
       assertSent(HttpMethod.GET, expectedListOperatingSystemsUriBuilder().toString());
    }
 
    private Uris.UriBuilder expectedListOperatingSystemsUriBuilder() {
       Uris.UriBuilder uriBuilder = Uris
             .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/infrastructure/operatingSystem");
-      uriBuilder.addQuery("datacenterId", "NA9");
+      uriBuilder.addQuery("datacenterId", "NA1", "NA9");
       return uriBuilder;
    }
 
+   private Uris.UriBuilder expectedListOperatingSystemsWithPaginationUriBuilder(int pageNumber) {
+      Uris.UriBuilder uriBuilder = Uris
+            .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/infrastructure/operatingSystem");
+      return addPageNumberToUriBuilder(uriBuilder.addQuery("datacenterId", "NA1", "NA9"), pageNumber, false);
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
index 1d7f427..b8e1c2b 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiLiveTest.java
@@ -18,9 +18,13 @@ package org.jclouds.dimensiondata.cloudcontrol.features;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget;
 import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange;
+import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Placement;
+import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock;
 import org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.jclouds.rest.ResourceAlreadyExistsException;
 import org.testng.annotations.AfterClass;
@@ -28,12 +32,16 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import java.util.List;
+import java.util.Date;
 
 import static org.jclouds.dimensiondata.cloudcontrol.features.NetworkApiMockTest.DEFAULT_ACTION;
 import static org.jclouds.dimensiondata.cloudcontrol.features.NetworkApiMockTest.DEFAULT_IP_VERSION;
 import static org.jclouds.dimensiondata.cloudcontrol.utils.DimensionDataCloudControlResponseUtils.generateFirewallRuleName;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertEquals;
 
 @Test(groups = "live", testName = "NetworkApiLiveTest", singleThreaded = true)
 public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest {
@@ -43,8 +51,14 @@ public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest
    private static final String DEFAULT_PROTOCOL = "TCP";
 
    private String networkDomainId;
+   private String networkDomainName;
    private String vlanId;
    private String portListId;
+   private String firewallRuleId;
+   private String publicIpv4BlockId;
+   private PublicIpBlock publicIpBlock;
+   private String natRuleId;
+
    private List<String> firewallRuleIds;
 
    @BeforeClass
@@ -61,28 +75,106 @@ public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest
    }
 
    @Test(dependsOnMethods = "testCreatePortList")
+   public void testGetPortList() {
+      FirewallRuleTarget.PortList portList = api().getPortList(portListId);
+      assertNotNull(portList);
+      assertTrue(portList.port().get(0).begin() == 22);
+   }
+
+   @Test(dependsOnMethods = "testGetPortList")
    public void testCreateFirewallRuleWithPortList() {
-      String id = api().createFirewallRule(networkDomainId, generateFirewallRuleName("server-id"), DEFAULT_ACTION,
+      firewallRuleId = api().createFirewallRule(networkDomainId, generateFirewallRuleName("server-id"), DEFAULT_ACTION,
             DEFAULT_IP_VERSION, DEFAULT_PROTOCOL, FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(),
             FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).portListId(portListId).build(), Boolean.TRUE,
             Placement.builder().position("LAST").build());
-      firewallRuleIds.add(id);
+      firewallRuleIds.add(firewallRuleId);
+   }
+
+   @Test(dependsOnMethods = "testCreateFirewallRuleWithPortList")
+   public void testListFirewallRules() {
+      PagedIterable<FirewallRule> firewallRulesList = api().listFirewallRules(networkDomainId);
+      assertFalse(firewallRulesList.isEmpty());
+      assertEquals(firewallRulesList.last().get().first().get().networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testListFirewallRules")
+   public void testDeleteFirewallRule() {
+      api().deleteFirewallRule(firewallRuleId);
+      FirewallRule rule = findById(api().listFirewallRules(networkDomainId).concat().toList(), firewallRuleId);
+      assertNull(rule);
    }
 
    @Test(dependsOnMethods = "testDeployNetworkDomain")
    public void testDeployVlan() {
-      vlanId = api().deployVlan(networkDomainId, NetworkApiLiveTest.class.getSimpleName(),
-            NetworkApiLiveTest.class.getSimpleName(), DEFAULT_PRIVATE_IPV4_BASE_ADDRESS,
+      vlanId = api().deployVlan(networkDomainId, NetworkApiLiveTest.class.getSimpleName() + new Date().getTime(),
+            NetworkApiLiveTest.class.getSimpleName() + new Date().getTime(), DEFAULT_PRIVATE_IPV4_BASE_ADDRESS,
             DEFAULT_PRIVATE_IPV4_PREFIX_SIZE);
       assertNotNull(vlanId);
       assertTrue(vlanNormalPredicate.apply(vlanId), "vlan is not in a NORMAL state after timeout");
    }
 
    @Test
+   public void testAddPublicIPv4Block() {
+      publicIpv4BlockId = api().addPublicIpBlock(PREPARED_NETWORK_DOMAIN_ID);
+      assertNotNull(publicIpv4BlockId);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testListPublicIPv4AddressBlocks() {
+      PagedIterable<PublicIpBlock> ipBlockList = api().listPublicIPv4AddressBlocks(PREPARED_NETWORK_DOMAIN_ID);
+      assertTrue(!ipBlockList.isEmpty());
+      assertEquals(ipBlockList.last().get().first().get().size(), 2);
+      assertEquals(ipBlockList.last().get().first().get().networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testGetPublicIPv4AddressBlocks() {
+      publicIpBlock = api().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNotNull(publicIpBlock);
+      assertEquals(publicIpBlock.size(), 2);
+      assertEquals(publicIpBlock.networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
+   }
+
+   @Test(dependsOnMethods = "testGetPublicIPv4AddressBlocks")
+   public void testCreateNatRule() {
+      natRuleId = api()
+            .createNatRule(PREPARED_NETWORK_DOMAIN_ID, PREPARED_PRIVATE_IPV4_ADDRESS, publicIpBlock.baseIp());
+      assertNotNull(natRuleId);
+   }
+
+   @Test(dependsOnMethods = "testCreateNatRule")
+   public void testListNatRules() {
+      PagedIterable<NatRule> natRulesList = api().listNatRules(PREPARED_NETWORK_DOMAIN_ID);
+      assertTrue(!natRulesList.isEmpty());
+      assertEquals(natRulesList.last().get().first().get().networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
+   }
+
+   @Test(dependsOnMethods = { "testCreateNatRule", "testListNatRules" })
+   public void testGetNatRule() {
+      NatRule natRule = api().getNatRule(natRuleId);
+      assertNotNull(natRule);
+      assertEquals(natRule.networkDomainId(), PREPARED_NETWORK_DOMAIN_ID);
+   }
+
+   @Test(dependsOnMethods = "testGetNatRule", alwaysRun = true)
+   public void testDeleteNatRule() {
+      api().deleteNatRule(natRuleId);
+      NatRule natRule = api().getNatRule(natRuleId);
+      assertNull(natRule);
+   }
+
+   @Test(dependsOnMethods = "testDeleteNatRule")
+   public void testRemovePublicIpBlock() {
+      api().removePublicIpBlock(publicIpv4BlockId);
+      publicIpBlock = api().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNull(publicIpBlock);
+   }
+
+   @Test
    public void testDeployNetworkDomain() {
-      String networkDomainName = NetworkApiLiveTest.class.getSimpleName();
-      networkDomainId = api()
-            .deployNetworkDomain(DATACENTER, networkDomainName, NetworkApiLiveTest.class.getSimpleName(), "ESSENTIALS");
+      networkDomainName = NetworkApiLiveTest.class.getSimpleName() + new Date().getTime();
+      networkDomainId = api().deployNetworkDomain(DATACENTERS.iterator().next(), networkDomainName,
+            NetworkApiLiveTest.class.getSimpleName() + new Date().getTime() + "description", "ESSENTIALS");
       assertNotNull(networkDomainId);
       assertTrue(networkDomainNormalPredicate.apply(networkDomainId),
             "network domain is not in a NORMAL state after timeout");
@@ -90,8 +182,7 @@ public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest
 
    @Test(expectedExceptions = ResourceAlreadyExistsException.class)
    public void testDeploySameNetworkDomain() {
-      api().deployNetworkDomain(DATACENTER, NetworkApiLiveTest.class.getSimpleName(),
-            NetworkApiLiveTest.class.getSimpleName(), "ESSENTIALS");
+      api().deployNetworkDomain(DATACENTERS.iterator().next(), networkDomainName, networkDomainName, "ESSENTIALS");
    }
 
    @AfterClass
@@ -113,10 +204,21 @@ public class NetworkApiLiveTest extends BaseDimensionDataCloudControlApiLiveTest
          assertTrue(networkDomainDeletedPredicate.apply(networkDomainId),
                "network domain is not in a DELETED state after timeout");
       }
+      if (publicIpBlock != null) {
+         api().removePublicIpBlock(publicIpBlock.id());
+      }
    }
 
    private NetworkApi api() {
       return api.getNetworkApi();
    }
 
+   private FirewallRule findById(List<FirewallRule> collection, String id) {
+      for (FirewallRule rule : collection) {
+         if (rule.id().equals(id)) {
+            return rule;
+         }
+      }
+      return null;
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java
index 6e4fc86..5002a8b 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/NetworkApiMockTest.java
@@ -16,7 +16,9 @@
  */
 package org.jclouds.dimensiondata.cloudcontrol.features;
 
+import com.google.common.collect.Lists;
 import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
 import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.FirewallRuleTarget;
 import org.jclouds.dimensiondata.cloudcontrol.domain.IpRange;
@@ -32,6 +34,7 @@ import org.jclouds.http.Uris;
 import org.testng.annotations.Test;
 
 import javax.ws.rs.HttpMethod;
+import java.util.List;
 
 import static ch.qos.logback.core.net.ssl.SSL.DEFAULT_PROTOCOL;
 import static com.google.common.collect.Iterables.size;
@@ -51,7 +54,7 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
 
    public void testListNetworkDomains() throws Exception {
       server.enqueue(jsonResponse("/networkDomains.json"));
-      Iterable<NetworkDomain> networkDomains = api.getNetworkApi().listNetworkDomains().concat();
+      Iterable<NetworkDomain> networkDomains = api().listNetworkDomains().concat();
       assertEquals(size(networkDomains), 1); // Force the PagedIterable to advance
       assertEquals(server.getRequestCount(), 2);
 
@@ -61,30 +64,30 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
    public void testListNetworkDomainsWithPagination() throws Exception {
       server.enqueue(jsonResponse("/networkDomains-page1.json"));
       server.enqueue(jsonResponse("/networkDomains-page2.json"));
-      Iterable<NetworkDomain> networkDomains = api.getNetworkApi().listNetworkDomains().concat().toList();
+      Iterable<NetworkDomain> networkDomains = api().listNetworkDomains().concat().toList();
 
       consumeIterableAndAssertAdditionalPagesRequested(networkDomains, 20, 0);
 
       assertSent(HttpMethod.GET, expectedListNetworkDomainsUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNetworkDomainsUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNetworkDomainsUriBuilder(), 2, false).toString());
    }
 
    public void testGetNetworkDomain() throws Exception {
       server.enqueue(jsonResponse("/networkDomain.json"));
-      api.getNetworkApi().getNetworkDomain("networkDomainId");
+      api().getNetworkDomain("networkDomainId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain/networkDomainId");
    }
 
    public void testGetNetworkDomain_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
+      api().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain"
             + "?datacenterId=testDatacenterId&name=testName");
    }
 
    public void testListNetworkDomainsWithName() throws Exception {
       server.enqueue(jsonResponse("/networkDomains.json"));
-      api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
+      api().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain"
             + "?datacenterId=testDatacenterId&name=testName");
    }
@@ -104,21 +107,21 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
 
    public void testListNetworkDomainsWithName_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
+      api().listNetworkDomainsWithDatacenterIdAndName("testDatacenterId", "testName").concat();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/networkDomain"
             + "?datacenterId=testDatacenterId&name=testName");
    }
 
    public void testListVlansWithNetworkDomainId() throws Exception {
       server.enqueue(jsonResponse("/vlans.json"));
-      api.getNetworkApi().listVlans("testNetworkDomainId");
+      api().listVlans("testNetworkDomainId");
       assertSent(GET,
             "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=testNetworkDomainId");
    }
 
    public void testListVlansWithNetworkDomainId_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().listVlans("testNetworkDomainId");
+      api().listVlans("testNetworkDomainId");
       assertSent(GET,
             "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=testNetworkDomainId");
    }
@@ -126,60 +129,60 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
    public void testListVlanssWithPagination() throws Exception {
       server.enqueue(jsonResponse("/vlans-page1.json"));
       server.enqueue(jsonResponse("/vlans-page2.json"));
-      Iterable<Vlan> vlans = api.getNetworkApi().listVlans("12345").concat().toList();
+      Iterable<Vlan> vlans = api().listVlans("12345").concat().toList();
 
       consumeIterableAndAssertAdditionalPagesRequested(vlans, 20, 0);
 
       assertSent(HttpMethod.GET, expectedListVlansRulesUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListVlansRulesUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListVlansRulesUriBuilder(), 2, false).toString());
    }
 
    public void testListVlans() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/vlans.json")));
-      assertEquals(api.getNetworkApi().listVlans("12345").concat().toList(), new VlansParseTest().expected().toList());
+      assertEquals(api().listVlans("12345").concat().toList(), new VlansParseTest().expected().toList());
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=12345");
    }
 
    public void testListVlans_404() throws Exception {
       server.enqueue(response404());
-      assertTrue(api.getNetworkApi().listVlans("12345").concat().isEmpty());
+      assertTrue(api().listVlans("12345").concat().isEmpty());
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan?networkDomainId=12345");
    }
 
    public void testGetVlan() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/vlan.json")));
-      api.getNetworkApi().getVlan("12345");
+      api().getVlan("12345");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan/12345");
    }
 
    public void testGetVlan_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().getVlan("12345");
+      api().getVlan("12345");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/vlan/12345");
    }
 
    public void testListPublicIPv4AddressBlock() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/publicIpBlocks.json")));
-      assertEquals(api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().toList(),
+      assertEquals(api().listPublicIPv4AddressBlocks("12345").concat().toList(),
             new PublicIpBlocksParseTest().expected().toList());
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock?networkDomainId=12345");
    }
 
    public void testListPublicIPv4AddressBlock_404() throws Exception {
       server.enqueue(response404());
-      assertTrue(api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().isEmpty());
+      assertTrue(api().listPublicIPv4AddressBlocks("12345").concat().isEmpty());
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock?networkDomainId=12345");
    }
 
    public void testListPublicIPv4AddressBlockWithPagination() throws Exception {
       server.enqueue(jsonResponse("/publicIpBlocks-page1.json"));
       server.enqueue(jsonResponse("/publicIpBlocks-page2.json"));
-      Iterable<PublicIpBlock> ipBlocks = api.getNetworkApi().listPublicIPv4AddressBlocks("12345").concat().toList();
+      Iterable<PublicIpBlock> ipBlocks = api().listPublicIPv4AddressBlocks("12345").concat().toList();
 
       consumeIterableAndAssertAdditionalPagesRequested(ipBlocks, 20, 0);
 
       assertSent(HttpMethod.GET, expectedListPublicIpBlockUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListPublicIpBlockUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListPublicIpBlockUriBuilder(), 2, false).toString());
    }
 
    public void testCreateFirewallRule() throws Exception {
@@ -190,7 +193,7 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + "} ],\n" + "\"warning\": [],\n" + "\"error\": [],\n"
                   + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().createFirewallRule("123456", "test", DEFAULT_ACTION, DEFAULT_IP_VERSION, DEFAULT_PROTOCOL,
+      api().createFirewallRule("123456", "test", DEFAULT_ACTION, DEFAULT_IP_VERSION, DEFAULT_PROTOCOL,
             FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(),
             FirewallRuleTarget.builder().ip(IpRange.create("ANY", null)).build(), true,
             Placement.builder().position("LAST").build());
@@ -204,13 +207,13 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + " has been accepted and is being processed\", \"info\": [],\n" + "\"warning\": [],\n"
                   + "\"error\": [],\n" + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().deleteNetworkDomain("networkDomainId");
+      api().deleteNetworkDomain("networkDomainId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNetworkDomain");
    }
 
    public void testDeleteNetworkDomain_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().deleteNetworkDomain("networkDomainId");
+      api().deleteNetworkDomain("networkDomainId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNetworkDomain");
    }
 
@@ -221,25 +224,25 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + " \"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n"
                   + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().removePublicIpBlock("publicIpBlockId");
+      api().removePublicIpBlock("publicIpBlockId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/removePublicIpBlock");
    }
 
    public void testRemovePublicIpBlock_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().removePublicIpBlock("publicIpBlockId");
+      api().removePublicIpBlock("publicIpBlockId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/removePublicIpBlock");
    }
 
    public void testGetPublicIpBlock() throws Exception {
       server.enqueue(jsonResponse("/publicIpBlock.json"));
-      api.getNetworkApi().getPublicIPv4AddressBlock("publicIpBlockId");
+      api().getPublicIPv4AddressBlock("publicIpBlockId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock/publicIpBlockId");
    }
 
    public void testGetPublicIpBlock_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().getPublicIPv4AddressBlock("publicIpBlockId");
+      api().getPublicIPv4AddressBlock("publicIpBlockId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/publicIpBlock/publicIpBlockId");
    }
 
@@ -250,66 +253,66 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + "\"value\": \"dc545f3e-823c-4500-93c9-8d7f576311de\"\n" + "} ],\n" + "\"warning\": [],\n"
                   + "\"error\": [],\n" + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().createNatRule("networkDomainId", "10.0.0.5", "155.143.0.54");
+      api().createNatRule("networkDomainId", "10.0.0.5", "155.143.0.54");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/createNatRule");
    }
 
    public void testListNatRules() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/natRules.json")));
-      api.getNetworkApi().listNatRules("12345").concat().toList();
+      api().listNatRules("12345").concat().toList();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule?networkDomainId=12345");
    }
 
    public void testListNatRulesWithPagination() throws Exception {
       server.enqueue(jsonResponse("/natRules-page1.json"));
       server.enqueue(jsonResponse("/natRules-page2.json"));
-      Iterable<NatRule> natRules = api.getNetworkApi().listNatRules("12345").concat().toList();
+      Iterable<NatRule> natRules = api().listNatRules("12345").concat().toList();
 
       consumeIterableAndAssertAdditionalPagesRequested(natRules, 20, 0);
 
       assertSent(HttpMethod.GET, expectedListNatRulesUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNatRulesUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListNatRulesUriBuilder(), 2, false).toString());
    }
 
    public void testListNatRules_404() throws Exception {
       server.enqueue(response404());
-      assertTrue(api.getNetworkApi().listNatRules("12345").concat().isEmpty());
+      assertTrue(api().listNatRules("12345").concat().isEmpty());
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule?networkDomainId=12345");
    }
 
    public void testGetNatRule() throws Exception {
       server.enqueue(jsonResponse("/natRule.json"));
-      api.getNetworkApi().getNatRule("natRuleId");
+      api().getNatRule("natRuleId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule/natRuleId");
    }
 
    public void testGetNatRule_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().getNatRule("natRuleId");
+      api().getNatRule("natRuleId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/natRule/natRuleId");
    }
 
    public void testListFirewallRules() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/firewallRules.json")));
-      api.getNetworkApi().listFirewallRules("12345").concat().toList();
+      api().listFirewallRules("12345").concat().toList();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule?networkDomainId=12345");
    }
 
    public void testListFirewallRules_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().listFirewallRules("12345").concat().toList();
+      api().listFirewallRules("12345").concat().toList();
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule?networkDomainId=12345");
    }
 
    public void testListFirewallRulesWithPagination() throws Exception {
       server.enqueue(jsonResponse("/firewallRules-page1.json"));
       server.enqueue(jsonResponse("/firewallRules-page2.json"));
-      Iterable<FirewallRule> firewallRules = api.getNetworkApi().listFirewallRules("12345").concat().toList();
+      Iterable<FirewallRule> firewallRules = api().listFirewallRules("12345").concat().toList();
 
       consumeIterableAndAssertAdditionalPagesRequested(firewallRules, 15, 0);
 
       assertSent(HttpMethod.GET, expectedListFirewallRulesUriBuilder().toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListFirewallRulesUriBuilder(), 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(expectedListFirewallRulesUriBuilder(), 2, false).toString());
    }
 
    public void testDeleteFirewallRule() throws Exception {
@@ -319,25 +322,25 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + "\"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n"
                   + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().deleteFirewallRule("firewallRuleId");
+      api().deleteFirewallRule("firewallRuleId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteFirewallRule");
    }
 
    public void testDeleteFirewallRule_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().deleteFirewallRule("firewallRuleId");
+      api().deleteFirewallRule("firewallRuleId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteFirewallRule");
    }
 
    public void testGetPortList() throws Exception {
       server.enqueue(new MockResponse().setBody(payloadFromResource("/portList.json")));
-      api.getNetworkApi().getPortList("portListId");
+      api().getPortList("portListId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/portList/portListId");
    }
 
    public void testGetPortList_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().getPortList("portListId");
+      api().getPortList("portListId");
       assertSent(GET, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/portList/portListId");
    }
 
@@ -348,16 +351,130 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
                   + "\"warning\": [],\n" + "\"error\": [],\n"
                   + "\"requestId\": \"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
                   + "d5463212ef6a\" }"));
-      api.getNetworkApi().deletePortList("portListId");
+      api().deletePortList("portListId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deletePortList");
    }
 
    public void testDeletePortList_404() throws Exception {
       server.enqueue(response404());
-      api.getNetworkApi().deletePortList("portListId");
+      api().deletePortList("portListId");
       assertSent(POST, "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deletePortList");
    }
 
+   public void testDeployNetworkDomain() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DEPLOY_NETWORK_DOMAIN\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n"
+                  + "\"message\": \"Request to deploy Network Domain 'test' has been accepted and is being processed.\", "
+                  + "\"info\": [\n" + "{\n" + "\"name\": \"networkDomainId\",\n"
+                  + "\"value\": \"f14a871f-9a25-470c-aef8-51e13202e1aa\"\n" + "} ],\n" + "\"warning\": [],\n"
+                  + "\"error\": [],\n" + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46f2-9107-\n"
+                  + "9d52fe57d0ad\" }"));
+      api().deployNetworkDomain("NA9", "test", "test description", NetworkDomain.Type.ESSENTIALS.name());
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deployNetworkDomain");
+      assertBodyContains(recordedRequest,
+            "{\"datacenterId\":\"NA9\",\"name\":\"test\",\"description\":\"test description\",\"type\":\"ESSENTIALS\"}");
+   }
+
+   public void testDeployVlan() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DEPLOY_VLAN\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n"
+                  + "\"message\": \"Request to Deploy VLAN 'test' has been accepted and is being processed.\", "
+                  + "\"info\": [\n" + "{\n" + "\"name\": \"vlanId\",\n"
+                  + "\"value\": \"0e56433f-d808-4669-821d-812769517ff8\"\n" + "} ],\n" + "\"warning\": [],\n"
+                  + "\"error\": [],\n" + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46f2-9107-\n"
+                  + "9d52fe57d0ad\" }"));
+      api.getNetworkApi()
+            .deployVlan("f14a871f-9a25-470c-aef8-51e13202e1aa", "test", "test description", "10.0.3.0", 23);
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deployVlan");
+      assertBodyContains(recordedRequest,
+            "{\"networkDomainId\":\"f14a871f-9a25-470c-aef8-51e13202e1aa\",\"name\":\"test\","
+                  + "\"description\":\"test description\",\"privateIpv4BaseAddress\":\"10.0.3.0\",\"privateIpv4PrefixSize\":23}");
+   }
+
+   public void testDeleteVlan() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DELETE_VLAN\",\n" + "\"responseCode\": \"IN_PROGRESS\",\n"
+                  + "\"message\": \"Request to Delete VLAN (Id:0e56433f-d808-4669-821d-812769517ff8) has been accepted and is being processed.\", "
+                  + "\"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n"
+                  + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46f2-9107-\n"
+                  + "9d52fe57d0ad\" }"));
+      api().deleteVlan("0e56433f-d808-4669-821d-812769517ff8");
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteVlan");
+      assertBodyContains(recordedRequest, "{\"id\":\"0e56433f-d808-4669-821d-812769517ff8\"}");
+   }
+
+   public void testDeleteVlan_404() throws Exception {
+      server.enqueue(response404());
+      api().deleteVlan("0e56433f-d808-4669-821d-812769517ff8");
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteVlan");
+      assertBodyContains(recordedRequest, "{\"id\":\"0e56433f-d808-4669-821d-812769517ff8\"}");
+   }
+
+   public void testAddPublicIpBlock() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"ADD_PUBLIC_IP_BLOCK\",\n" + "\"responseCode\": \"OK\",\n"
+                  + "\"message\": \"Public IPv4 Address Block has been added successfully to"
+                  + "Network Domain 484174a2-ae74-4658-9e56-50fc90e086cf.\",\n" + "\"info\": [\n" + "{\n"
+                  + "\"name\": \"ipBlockId\",\n" + "\"value\": \"4487241a-f0ca-11e3-9315-d4bed9b167ba\"\n" + "} ],\n"
+                  + "\"warning\": [],\n" + "\"error\": [],\n"
+                  + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46"
+                  + "f2-9107-9d52fe57d0ad\" }"));
+      api().addPublicIpBlock("484174a2-ae74-4658-9e56-50fc90e086cf");
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/addPublicIpBlock");
+      assertBodyContains(recordedRequest, "{\"networkDomainId\":\"484174a2-ae74-4658-9e56-50fc90e086cf\"}");
+   }
+
+   public void testDeleteNatRule() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DELETE_NAT_RULE\",\n" + "\"responseCode\": \"OK\",\n"
+                  + "\"message\": \"NAT Rule with Id 2169a38e-5692-497e-a22a-701a838a6539 has been deleted.\", "
+                  + "\"info\": [],\n" + "\"warning\": [],\n" + "\"error\": [],\n"
+                  + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46f2-9107-\n"
+                  + "9d52fe57d0ad\" }"));
+      api().deleteNatRule("2169a38e-5692-497e-a22a-701a838a6539");
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNatRule");
+      assertBodyContains(recordedRequest, "{\"id\":\"2169a38e-5692-497e-a22a-701a838a6539\"}");
+   }
+
+   public void testDeleteNatRule_404() throws Exception {
+      server.enqueue(response404());
+      api().deleteNatRule("2169a38e-5692-497e-a22a-701a838a6539");
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/deleteNatRule");
+      assertBodyContains(recordedRequest, "{\"id\":\"2169a38e-5692-497e-a22a-701a838a6539\"}");
+   }
+
+   public void testCreatePortList() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"CREATE_PORT_LIST\",\n" + "\"responseCode\": \"OK\",\n"
+                  + "\"message\": \"Port List 'TestPortList' has been created.\", " + "\"info\": [\n" + "{\n"
+                  + "\"name\": \"portListId\",\n" + "\"value\": \"9e6b496d-5261-4542-91aa-b50c7f569c54\"\n" + "} ],\n"
+                  + "\"warning\": [],\n" + "\"error\": [],\n"
+                  + "\"requestId\": \"NA9/2017-03-05T13:46:34.848-05:00/7e9fffe7-190b-46f2-9107-\n"
+                  + "9d52fe57d0ad\" }"));
+      List<FirewallRuleTarget.Port> portList = Lists
+            .newArrayList(FirewallRuleTarget.Port.create(8080, null), FirewallRuleTarget.Port.create(8899, 9023),
+                  FirewallRuleTarget.Port.create(9500, null));
+      List<String> childPortListId = Lists
+            .newArrayList("1ecf8cd4-dcda-4783-b4ba-b50eb541b813", "54da883e-a023-11e5-a668-426c57702d90");
+      api.getNetworkApi()
+            .createPortList("db707da6-5785-4a56-ad58-2f8058708d95", "TestPortList", "Test Port List", portList,
+                  childPortListId);
+      RecordedRequest recordedRequest = assertSent(POST,
+            "/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/createPortList");
+      assertBodyContains(recordedRequest,
+            "{\"networkDomainId\":\"db707da6-5785-4a56-ad58-2f8058708d95\",\"name\":\"TestPortList\","
+                  + "\"description\":\"Test Port List\",\"port\":["
+                  + "{\"begin\":8080},{\"begin\":8899,\"end\":9023},{\"begin\":9500}],"
+                  + "\"childPortListId\":[\"1ecf8cd4-dcda-4783-b4ba-b50eb541b813\",\"54da883e-a023-11e5-a668-426c57702d90\"]}");
+   }
+
    private Uris.UriBuilder expectedListFirewallRulesUriBuilder() {
       Uris.UriBuilder uriBuilder = Uris
             .uriBuilder("/caas/" + VERSION + "/6ac1e746-b1ea-4da5-a24e-caf1a978789d/network/firewallRule");
@@ -389,4 +506,8 @@ public class NetworkApiMockTest extends BaseAccountAwareCloudControlMockTest {
       uriBuilder.addQuery("networkDomainId", "12345");
       return uriBuilder;
    }
+
+   private NetworkApi api() {
+      return api.getNetworkApi();
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
index 4a1b05a..4d004e9 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiLiveTest.java
@@ -60,6 +60,13 @@ public class ServerImageApiLiveTest extends BaseDimensionDataCloudControlApiLive
       }
    }
 
+   @Test
+   public void testGetCustomerImage() {
+      CustomerImage customerImage = api().getCustomerImage(PREPARED_CUSTOMER_IMAGE_ID);
+      assertNotNull(customerImage);
+      assertTrue(customerImage.datacenterId().equals("NA9"));
+   }
+
    private FluentIterable<CustomerImage> getCustomerImages() {
       FluentIterable<CustomerImage> customerImages = api().listCustomerImages().concat();
       assertNotNull(customerImages);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiMockTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiMockTest.java
index 1d45ff0..8738903 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApiMockTest.java
@@ -70,7 +70,7 @@ public class ServerImageApiMockTest extends BaseAccountAwareCloudControlMockTest
 
       Uris.UriBuilder uriBuilder = getListOsImageUrl();
       assertSent(HttpMethod.GET, uriBuilder.toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(uriBuilder, 2).toString());
+      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(uriBuilder, 2, false).toString());
    }
 
    public void testListOsImage_404() throws Exception {
@@ -121,7 +121,7 @@ public class ServerImageApiMockTest extends BaseAccountAwareCloudControlMockTest
       Uris.UriBuilder uriBuilder = getListCustomerImageUrl();
 
       assertSent(HttpMethod.GET, uriBuilder.toString());
-      assertSent(HttpMethod.GET, addPageNumberToUriBuilder(uriBuilder, 2).toString());
+      assertSent(HttpMethod.GET, addZonesToUriBuilder(addPageNumberToUriBuilder(uriBuilder, 2, true)).toString());
    }
 
    public void testListCustomerImage_404() throws Exception {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiMockTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiMockTest.java
index 9a0d8c8..0f35cda 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiMockTest.java
@@ -100,7 +100,7 @@ public class TagApiMockTest extends BaseAccountAwareCloudControlMockTest {
       consumeIterableAndAssertAdditionalPagesRequested(tags, 8, 0);
 
       assertSent(GET, expectedListTagsUriBuilder().toString());
-      assertSent(GET, addPageNumberToUriBuilder(expectedListTagsUriBuilder(), 2).toString());
+      assertSent(GET, addPageNumberToUriBuilder(expectedListTagsUriBuilder(), 2, true).toString());
    }
 
    @Test
@@ -128,7 +128,7 @@ public class TagApiMockTest extends BaseAccountAwareCloudControlMockTest {
       consumeIterableAndAssertAdditionalPagesRequested(tagKeys, 18, 0);
 
       assertSent(GET, expectedListTagKeysUriBuilder().toString());
-      assertSent(GET, addPageNumberToUriBuilder(expectedListTagKeysUriBuilder(), 2).toString());
+      assertSent(GET, addPageNumberToUriBuilder(expectedListTagKeysUriBuilder(), 2, true).toString());
    }
 
    private Uris.UriBuilder expectedListTagKeysUriBuilder() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
index affbe16..cd3e148 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlApiLiveTest.java
@@ -17,21 +17,30 @@
 package org.jclouds.dimensiondata.cloudcontrol.internal;
 
 import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
 import com.google.inject.Injector;
 import com.google.inject.Key;
 import com.google.inject.Module;
 import com.google.inject.TypeLiteral;
 import com.google.inject.name.Names;
+import org.jclouds.ContextBuilder;
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.apis.BaseApiLiveTest;
+import org.jclouds.concurrent.config.ExecutorServiceModule;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApiMetadata;
+import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlProviderMetadata;
+import org.jclouds.location.suppliers.ZoneIdsSupplier;
 import org.jclouds.logging.config.LoggingModule;
 import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.rest.ApiContext;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import java.util.Properties;
+import java.util.Set;
 
+import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.NETWORK_DOMAIN_DELETED_PREDICATE;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.NETWORK_DOMAIN_NORMAL_PREDICATE;
 import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudControlComputeServiceContextModule.SERVER_DELETED_PREDICATE;
@@ -45,11 +54,27 @@ import static org.jclouds.dimensiondata.cloudcontrol.config.DimensionDataCloudCo
 @Test(groups = "live")
 public class BaseDimensionDataCloudControlApiLiveTest extends BaseApiLiveTest<DimensionDataCloudControlApi> {
 
+   private static final Set<Module> modules = ImmutableSet.<Module>of(new ExecutorServiceModule(sameThreadExecutor()));
+
+   protected static final String PREPARED_CUSTOMER_IMAGE_ID = "fb438e00-10f8-47ac-a434-f3f9461c3a76";
+
    protected static final String NETWORK_DOMAIN_ID = System
          .getProperty("networkDomainId", "690de302-bb80-49c6-b401-8c02bbefb945");
    protected static final String VLAN_ID = System.getProperty("vlanId", "6b25b02e-d3a2-4e69-8ca7-9bab605deebd");
    protected static final String IMAGE_ID = System.getProperty("imageId", "4c02126c-32fc-4b4c-9466-9824c1b5aa0f");
-   protected static final String DATACENTER = System.getProperty("datacenter", "NW20-EPC-LAB04");
+
+   protected static final String PREPARED_NETWORK_DOMAIN_ID = System
+         .getProperty("networkDomainId", "d122949b-8990-46d6-98f0-91c8676fc720");
+   protected static final String PREPARED_PRIVATE_IPV4_ADDRESS = "10.0.0.6";
+   protected static ApiContext<DimensionDataCloudControlApi> ctx;
+   protected static Set<String> DATACENTERS;
+
+   @BeforeClass
+   public static void setUp() {
+      ctx = ContextBuilder.newBuilder(DimensionDataCloudControlProviderMetadata.builder().build()).credentials("", "")
+            .modules(modules).overrides(new Properties()).build();
+      DATACENTERS = ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+   }
    protected static final String SERVER_ID = System.getProperty("serverId", "b1c537bb-018c-49ba-beef-e0600e948149");
 
    protected Predicate<String> vlanDeletedPredicate;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/9c74d22b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
----------------------------------------------------------------------
diff --git a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
index 7856524..69707b4 100644
--- a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
+++ b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/internal/BaseDimensionDataCloudControlMockTest.java
@@ -31,6 +31,7 @@ import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlProviderMetadata;
 import org.jclouds.http.Uris;
 import org.jclouds.json.Json;
+import org.jclouds.location.suppliers.ZoneIdsSupplier;
 import org.jclouds.rest.ApiContext;
 import org.testng.IHookCallBack;
 import org.testng.IHookable;
@@ -205,8 +206,18 @@ public class BaseDimensionDataCloudControlMockTest implements IHookable {
       assertEquals(server.getRequestCount() - initialRequestCount, expectedAdditionalPagesRequested);
    }
 
-   protected Uris.UriBuilder addPageNumberToUriBuilder(Uris.UriBuilder uriBuilder, int pageNumber) {
-      uriBuilder.addQuery("pageNumber", Integer.toString(pageNumber));
+   protected Uris.UriBuilder addPageNumberToUriBuilder(Uris.UriBuilder uriBuilder, int pageNumber, boolean clearQuery) {
+      if (clearQuery){
+         uriBuilder.clearQuery();
+      }
+      return uriBuilder.addQuery("pageNumber", Integer.toString(pageNumber));
+   }
+
+   protected Uris.UriBuilder addZonesToUriBuilder(Uris.UriBuilder uriBuilder) {
+      Set<String> zones = ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+      for (String zone : zones) {
+         uriBuilder.addQuery("datacenterId", zone);
+      }
       return uriBuilder;
    }