Repository: jclouds-labs
Updated Branches:
  refs/heads/2.1.x 6b4aa2c85 -> f7b8c2caf


JCLOUDS-1431 - Support AU geo for Live Tests.


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

Branch: refs/heads/2.1.x
Commit: f7b8c2cafd388409a8658e0a70c676f6994a9e51
Parents: 6b4aa2c
Author: Trevor Flanagan <[email protected]>
Authored: Thu Oct 18 20:08:00 2018 +0100
Committer: Ignasi Barrera <[email protected]>
Committed: Fri Oct 19 10:47:07 2018 +0200

----------------------------------------------------------------------
 .../DimensionDataCloudControlApi.java           |   4 +
 .../DimensionDataCloudControlApiMetadata.java   |   2 +-
 ...mensionDataCloudControlProviderMetadata.java |   3 +-
 ...CloudControlComputeServiceContextModule.java |  31 +++
 .../cloudcontrol/domain/CustomerImage.java      |   6 +-
 .../cloudcontrol/domain/OsImage.java            |   2 +
 .../cloudcontrol/features/AccountApi.java       |   2 +-
 .../cloudcontrol/features/CustomerImageApi.java |  47 ++++
 .../features/InfrastructureApi.java             |   2 +-
 .../cloudcontrol/features/NetworkApi.java       |   2 +-
 .../cloudcontrol/features/ServerApi.java        |   2 +-
 .../cloudcontrol/features/ServerImageApi.java   |   2 +-
 .../cloudcontrol/features/TagApi.java           |   2 +-
 .../filters/OrganisationIdFilter.java           |   1 -
 .../functions/BaseImageToHardwareTest.java      |   3 +-
 .../features/CustomerImageApiMockTest.java      |  47 ++++
 .../features/NetworkApiLiveTest.java            |  69 ------
 .../features/ServerApiLiveTest.java             | 218 +++++++++++++++++--
 .../features/ServerImageApiLiveTest.java        |  23 --
 .../cloudcontrol/features/TagApiLiveTest.java   |  43 +---
 ...aseDimensionDataCloudControlApiLiveTest.java |  31 ++-
 .../BaseDimensionDataCloudControlMockTest.java  |   2 +-
 .../parse/CustomerImagesParseTest.java          |   3 +-
 23 files changed, 373 insertions(+), 174 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
index ce8c1a6..9824357 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApi.java
@@ -17,6 +17,7 @@
 package org.jclouds.dimensiondata.cloudcontrol;
 
 import org.jclouds.dimensiondata.cloudcontrol.features.AccountApi;
+import org.jclouds.dimensiondata.cloudcontrol.features.CustomerImageApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.InfrastructureApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.ServerApi;
@@ -45,4 +46,7 @@ public interface DimensionDataCloudControlApi extends 
Closeable {
 
    @Delegate
    TagApi getTagApi();
+
+   @Delegate
+   CustomerImageApi getCustomerImageApi();
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
index a352129..3a39c16 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlApiMetadata.java
@@ -54,7 +54,7 @@ public class DimensionDataCloudControlApiMetadata extends 
BaseHttpApiMetadata<Di
          id("dimensiondata-cloudcontrol").name("DimensionData CloudControl 
API").identityName("user name")
                .credentialName("user password")
                
.documentation(URI.create("http://www.dimensiondata.com/en-US/Solutions/Cloud";))
-               
.defaultEndpoint("https://api-REGION.dimensiondata.com/caas";).version("2.4")
+               
.defaultEndpoint("https://api-REGION.dimensiondata.com";).version("2.4")
                
.defaultProperties(defaultProperties).view(typeToken(ComputeServiceContext.class)).defaultModules(
                ImmutableSet.<Class<? extends 
Module>>builder().add(DimensionDataCloudControlHttpApiModule.class)
                      .add(DimensionDataCloudControlParserModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
index f25cd15..db4303d 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/DimensionDataCloudControlProviderMetadata.java
@@ -81,8 +81,7 @@ public class DimensionDataCloudControlProviderMetadata 
extends BaseProviderMetad
          id("dimensiondata-cloudcontrol").name("DimensionData Cloud Control")
                .apiMetadata(new DimensionDataCloudControlApiMetadata())
                .homepage(URI.create("https://na-cloud.dimensiondata.com/";))
-               .console(URI.create("https://na-cloud.dimensiondata.com/";))
-               .endpoint("https://api-na.dimensiondata.com/caas";)
+               
.console(URI.create("https://na-cloud.dimensiondata.com/";)).endpoint("https://api-na.dimensiondata.com";)
                
.defaultProperties(DimensionDataCloudControlProviderMetadata.defaultProperties());
       }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
index dca9512..c85128a 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/config/DimensionDataCloudControlComputeServiceContextModule.java
@@ -22,6 +22,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.dimensiondata.cloudcontrol.DimensionDataCloudControlApi;
+import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkDomain;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Server;
 import org.jclouds.dimensiondata.cloudcontrol.domain.State;
@@ -29,6 +30,7 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.Vlan;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import org.jclouds.dimensiondata.cloudcontrol.features.NetworkApi;
 import org.jclouds.dimensiondata.cloudcontrol.features.ServerApi;
+import org.jclouds.dimensiondata.cloudcontrol.features.ServerImageApi;
 import org.jclouds.logging.Logger;
 
 import javax.annotation.Resource;
@@ -52,6 +54,7 @@ public class 
DimensionDataCloudControlComputeServiceContextModule extends Abstra
    public static final String SERVER_DELETED_PREDICATE = 
"SERVER_DELETED_PREDICATE";
    public static final String SERVER_NORMAL_PREDICATE = 
"SERVER_NORMAL_PREDICATE";
    public static final String VM_TOOLS_RUNNING_PREDICATE = 
"VM_TOOLS_RUNNING_PREDICATE";
+   public static final String CUSTOMER_IMAGE_DELETED_PREDICATE = 
"CUSTOMER_IMAGE_DELETED_PREDICATE";
 
    @Override
    protected void configure() {
@@ -132,6 +135,14 @@ public class 
DimensionDataCloudControlComputeServiceContextModule extends Abstra
             pollPeriod.pollMaxPeriod);
    }
 
+   @Provides
+   @Named(CUSTOMER_IMAGE_DELETED_PREDICATE)
+   protected Predicate<String> provideCustomerImageDeletedPredicate(final 
DimensionDataCloudControlApi api,
+         @Named(OPERATION_TIMEOUT) final Long operationTimeout, final 
ComputeServiceConstants.PollPeriod pollPeriod) {
+      return retry(new CustomerImageState(api.getServerImageApi(), 
State.DELETED), operationTimeout,
+            pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+   }
+
    private class VlanState implements Predicate<String> {
 
       private final State state;
@@ -249,4 +260,24 @@ public class 
DimensionDataCloudControlComputeServiceContextModule extends Abstra
          return vmTools != null && vmTools.runningStatus() == 
VmTools.RunningStatus.RUNNING;
       }
    }
+
+   private class CustomerImageState implements Predicate<String> {
+
+      private final State state;
+      private final ServerImageApi serverImageApi;
+
+      private CustomerImageState(final ServerImageApi serverImageApi, final 
State state) {
+         this.serverImageApi = serverImageApi;
+         this.state = state;
+      }
+
+      @Override
+      public boolean apply(final String customerImageId) {
+         checkNotNull(customerImageId, "customerImageId");
+         logger.trace("looking for state on customer image %s", 
customerImageId);
+         final CustomerImage customerImage = 
serverImageApi.getCustomerImage(customerImageId);
+         final boolean isDeleted = customerImage == null && state == 
State.DELETED;
+         return isDeleted || (customerImage != null && customerImage.state() 
== state);
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
index a549ef7..e167851 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/CustomerImage.java
@@ -41,7 +41,7 @@ public abstract class CustomerImage extends BaseImage {
          "softwareLabel", "createTime", "state", "tag", "progress", 
"virtualHardware", "source" })
    public static CustomerImage create(String id, String name, String 
description, Cluster cluster, Guest guest,
          String datacenterId, CPU cpu, int memoryGb, List<ImageNic> nics, 
List<Disk> disk, List<String> softwareLabel,
-         Date createTime, String state, List<TagWithIdAndName> tags, Progress 
progress, VirtualHardware virtualHardware,
+         Date createTime, State state, List<TagWithIdAndName> tags, Progress 
progress, VirtualHardware virtualHardware,
          Source source) {
       return 
builder().id(id).datacenterId(datacenterId).name(name).description(description).cluster(cluster)
             
.guest(guest).cpu(cpu).memoryGb(memoryGb).nics(nics).disks(disk).softwareLabels(softwareLabel)
@@ -49,7 +49,7 @@ public abstract class CustomerImage extends BaseImage {
             .source(source).build();
    }
 
-   public abstract String state();
+   public abstract State state();
 
    @Nullable
    public abstract List<TagWithIdAndName> tags();
@@ -96,7 +96,7 @@ public abstract class CustomerImage extends BaseImage {
 
       public abstract Builder createTime(Date createTime);
 
-      public abstract Builder state(String state);
+      public abstract Builder state(State state);
 
       public abstract Builder progress(Progress progress);
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
index 7b179e5..a64c7a5 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/domain/OsImage.java
@@ -18,6 +18,7 @@ package org.jclouds.dimensiondata.cloudcontrol.domain;
 
 import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
 import java.util.Date;
@@ -31,6 +32,7 @@ public abstract class OsImage extends BaseImage {
       type = TYPE;
    }
 
+   @Nullable
    public abstract String osImageKey();
 
    @SerializedNames({ "id", "name", "description", "cluster", "guest", 
"datacenterId", "cpu", "memoryGb", "nic", "disk",

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
index 7a2740c..d3f782e 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/AccountApi.java
@@ -30,7 +30,7 @@ import java.io.Closeable;
 
 @RequestFilters({ BasicAuthentication.class })
 @Consumes("application/json")
-@Path("/{jclouds.api-version}/user")
+@Path("/caas/{jclouds.api-version}/user")
 public interface AccountApi extends Closeable {
    @Named("myuser:get")
    @Path("/myUser")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
new file mode 100644
index 0000000..df2dce4
--- /dev/null
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApi.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.dimensiondata.cloudcontrol.features;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.dimensiondata.cloudcontrol.filters.OrganisationIdFilter;
+import org.jclouds.http.filters.BasicAuthentication;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/caas/2.7/image")
+public interface CustomerImageApi {
+
+   @Named("image:deleteCustomerImage")
+   @POST
+   @Path("/deleteCustomerImage")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindToJsonPayload.class)
+   @Fallback(Fallbacks.FalseOnNotFoundOr404.class)
+   boolean deleteCustomerImage(@PayloadParam("id") String id);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 2d76048..4961a28 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
@@ -50,7 +50,7 @@ import javax.ws.rs.core.MediaType;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/infrastructure")
+@Path("/caas/{jclouds.api-version}/infrastructure")
 public interface InfrastructureApi {
 
    @Named("infrastructure:datacenter")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 2a4629b..c46ae38 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
@@ -68,7 +68,7 @@ import java.util.List;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/network")
+@Path("/caas/{jclouds.api-version}/network")
 public interface NetworkApi {
 
    @Named("network:deployNetworkDomain")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
index 7c0cd1b..e3062ab 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApi.java
@@ -61,7 +61,7 @@ import java.util.List;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/server")
+@Path("/caas/{jclouds.api-version}/server")
 public interface ServerApi {
 
    @Named("server:list")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
index 57c560c..8a4f249 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerImageApi.java
@@ -50,7 +50,7 @@ import javax.ws.rs.core.MediaType;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/image")
+@Path("/caas/{jclouds.api-version}/image")
 public interface ServerImageApi {
 
    @Named("image:listOsImages")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
index 9b717ec..daebc31 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApi.java
@@ -58,7 +58,7 @@ import java.util.List;
 
 @RequestFilters({ BasicAuthentication.class, OrganisationIdFilter.class })
 @Consumes(MediaType.APPLICATION_JSON)
-@Path("/{jclouds.api-version}/tag")
+@Path("/caas/{jclouds.api-version}/tag")
 public interface TagApi {
 
    @Named("tag:createTagKey")

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
index cf1ec1b..daf5951 100644
--- 
a/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
+++ 
b/dimensiondata/src/main/java/org/jclouds/dimensiondata/cloudcontrol/filters/OrganisationIdFilter.java
@@ -32,7 +32,6 @@ import java.util.List;
 
 /**
  * Accepts requests and modifies the endpoint path so that it is injected with 
the organisation id.
- * Handles both oec and caas based URLs.
  */
 @Singleton
 public class OrganisationIdFilter implements HttpRequestFilter {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
index ca90da2..77531d8 100644
--- 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
+++ 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/compute/functions/BaseImageToHardwareTest.java
@@ -31,6 +31,7 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.Guest;
 import org.jclouds.dimensiondata.cloudcontrol.domain.ImageNic;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
+import org.jclouds.dimensiondata.cloudcontrol.domain.State;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VirtualHardware;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import org.testng.annotations.BeforeMethod;
@@ -91,7 +92,7 @@ public class BaseImageToHardwareTest {
                   
.of(Disk.builder().id("1bddd4ed-67dc-4e5e-a0d5-b5a6c012ec14").scsiId(0).sizeGb(50)
                         .speed("HIGHPERFORMANCE").build()))
             .createTime(new 
SimpleDateFormatDateService().iso8601DateParse("2016-07-17T23:53:48.000Z"))
-            
.datacenterId("QA1_N2_VMWARE_1").state("FAILED_ADD").guest(Guest.builder().operatingSystem(
+            
.datacenterId("QA1_N2_VMWARE_1").state(State.FAILED_ADD).guest(Guest.builder().operatingSystem(
                   
OperatingSystem.builder().id("WIN2012DC64").displayName("WIN2012DC/64").family("WINDOWS").build())
                   
.vmTools(VmTools.builder().versionStatus(VmTools.VersionStatus.CURRENT)
                         
.runningStatus(VmTools.RunningStatus.NOT_RUNNING).apiVersion(9354)

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
new file mode 100644
index 0000000..40e71eb
--- /dev/null
+++ 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/CustomerImageApiMockTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.dimensiondata.cloudcontrol.features;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import 
org.jclouds.dimensiondata.cloudcontrol.internal.BaseAccountAwareCloudControlMockTest;
+import org.testng.annotations.Test;
+
+import static javax.ws.rs.HttpMethod.POST;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+@Test(groups = "unit", testName = "CustomerImageApiMockTest", singleThreaded = 
true)
+public class CustomerImageApiMockTest extends 
BaseAccountAwareCloudControlMockTest {
+
+   public void testDeleteCustomerImage() throws Exception {
+      server.enqueue(new MockResponse().setResponseCode(200).setBody(
+            "{\n" + "\"operation\": \"DELETE_CUSTOMER_IMAGE\",\n" + 
"\"responseCode\": \"IN_PROGRESS\",\n"
+                  + "\"message\": \"Request to Delete Customer Image has been 
accepted. Please use appropriate Get or List API for status.\"\n"
+                  + "\"requestId\": 
\"NA9/2015-03-05T13:46:34.848-05:00/f8fdef24-8a12-45ea-a831-\n"
+                  + "d5463212ef6a\" }"));
+      boolean deleted = api.getCustomerImageApi().deleteCustomerImage("id");
+      assertSent(POST, 
"/caas/2.7/6ac1e746-b1ea-4da5-a24e-caf1a978789d/image/deleteCustomerImage");
+      assertTrue(deleted);
+   }
+
+   public void testDeleteCustomerImage_404() throws Exception {
+      server.enqueue(response404());
+      boolean deleted = 
api.getCustomerImageApi().deleteCustomerImage("networkDomainId");
+      assertSent(POST, 
"/caas/2.7/6ac1e746-b1ea-4da5-a24e-caf1a978789d/image/deleteCustomerImage");
+      assertFalse(deleted);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 020c0b2..6cfdafe 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
@@ -22,9 +22,7 @@ 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;
@@ -46,18 +44,11 @@ import static org.testng.Assert.assertTrue;
 @Test(groups = "live", testName = "NetworkApiLiveTest", singleThreaded = true)
 public class NetworkApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest {
 
-   private static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = "10.0.0.0";
-   private static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24;
-   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;
 
@@ -114,63 +105,6 @@ public class NetworkApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest
    }
 
    @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() {
       networkDomainName = NetworkApiLiveTest.class.getSimpleName() + new 
Date().getTime();
       networkDomainId = 
api().deployNetworkDomain(datacenters.iterator().next(), networkDomainName,
@@ -204,9 +138,6 @@ 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() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
index e30f92c..9fd3e91 100644
--- 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
+++ 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/ServerApiLiveTest.java
@@ -16,21 +16,38 @@
  */
 package org.jclouds.dimensiondata.cloudcontrol.features;
 
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
+import org.jclouds.collect.PagedIterable;
 import org.jclouds.dimensiondata.cloudcontrol.domain.CpuSpeed;
+import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Disk;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NIC;
+import org.jclouds.dimensiondata.cloudcontrol.domain.NatRule;
 import org.jclouds.dimensiondata.cloudcontrol.domain.NetworkInfo;
+import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
+import org.jclouds.dimensiondata.cloudcontrol.domain.PublicIpBlock;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Server;
+import org.jclouds.dimensiondata.cloudcontrol.domain.Tag;
+import org.jclouds.dimensiondata.cloudcontrol.domain.TagInfo;
 import 
org.jclouds.dimensiondata.cloudcontrol.domain.options.CloneServerOptions;
 import 
org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
+import org.jclouds.dimensiondata.cloudcontrol.options.DatacenterIdListFilters;
 import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 
 @Test(groups = "live", testName = "ServerApiLiveTest", singleThreaded = true)
@@ -39,10 +56,25 @@ public class ServerApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest
    private String serverId;
    private String cloneImageId;
    private final String deployedServerName = 
ServerApiLiveTest.class.getSimpleName() + System.currentTimeMillis();
+   private String vlanId;
+   private String networkDomainId;
+   private String imageId;
+   private String tagKeyId;
+   private String publicIpv4BlockId;
+   private PublicIpBlock publicIpBlock;
+   private String natRuleId;
+
+   @BeforeClass
+   public void init() {
+      final String datacenterId = deployNetworkDomain();
+      deployVlan();
+      findOsImage(datacenterId);
+      tagKeyId = createTagKey();
+   }
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testListServers() {
-      List<Server> servers = api().listServers().concat().toList();
+      List<Server> servers = 
api.getServerApi().listServers().concat().toList();
       assertNotNull(servers);
       boolean foundDeployedServer = false;
       for (Server s : servers) {
@@ -58,9 +90,10 @@ public class ServerApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest
    public void testDeployAndStartServer() {
       Boolean started = Boolean.TRUE;
       NetworkInfo networkInfo = NetworkInfo
-            .create(NETWORK_DOMAIN_ID, NIC.builder().vlanId(VLAN_ID).build(), 
Lists.<NIC>newArrayList());
+            .create(networkDomainId, NIC.builder().vlanId(vlanId).build(), 
Lists.<NIC>newArrayList());
       List<Disk> disks = 
ImmutableList.of(Disk.builder().scsiId(0).speed("STANDARD").build());
-      serverId = api().deployServer(deployedServerName, IMAGE_ID, started, 
networkInfo, "P$$ssWwrrdGoDd!", disks, null);
+      serverId = api.getServerApi()
+            .deployServer(deployedServerName, imageId, started, networkInfo, 
"P$$ssWwrrdGoDd!", disks, null);
       assertNotNull(serverId);
       assertTrue(serverStartedPredicate.apply(serverId), "server did not start 
after timeout");
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL 
after timeout");
@@ -68,55 +101,212 @@ public class ServerApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testReconfigureServer() {
-      api().reconfigureServer(serverId, 4, CpuSpeed.HIGHPERFORMANCE.name(), 1);
+      api.getServerApi().reconfigureServer(serverId, 4, 
CpuSpeed.HIGHPERFORMANCE.name(), 1);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL 
after timeout");
    }
 
    @Test(dependsOnMethods = "testDeployAndStartServer")
+   public void testApplyTagToServer() {
+      api.getTagApi()
+            .applyTags(serverId, "SERVER", 
Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
+   }
+
+   @Test(dependsOnMethods = "testApplyTagToServer")
+   public void testListTags() {
+      PagedIterable<Tag> response = api.getTagApi().listTags();
+      assertTrue(FluentIterable.from(response.concat().toList()).anyMatch(new 
Predicate<Tag>() {
+         @Override
+         public boolean apply(Tag input) {
+            return input.tagKeyId().equals(tagKeyId);
+         }
+      }), String.format("Couldn't find tagKeyId %s in listTags response", 
tagKeyId));
+   }
+
+   @Test(dependsOnMethods = "testListTags")
+   public void testRemoveTagFromServer() {
+      api.getTagApi().removeTags(serverId, "SERVER", 
Collections.singletonList(tagKeyId));
+      
assertFalse(FluentIterable.from(api.getTagApi().listTags().concat().toList()).anyMatch(new
 Predicate<Tag>() {
+         @Override
+         public boolean apply(Tag input) {
+            return input.tagKeyId().equals(tagKeyId);
+         }
+      }));
+   }
+
+   @Test(dependsOnMethods = "testDeployAndStartServer")
    public void testRebootServer() {
-      api().rebootServer(serverId);
+      api.getServerApi().rebootServer(serverId);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL 
after timeout");
       assertTrue(vmtoolsRunningPredicate.apply(serverId), "server vm tools not 
running after timeout");
    }
 
+   @Test(dependsOnMethods = "testDeployAndStartServer")
+   public void testAddPublicIPv4Block() {
+      publicIpv4BlockId = 
api.getNetworkApi().addPublicIpBlock(networkDomainId);
+      assertNotNull(publicIpv4BlockId);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testListPublicIPv4AddressBlocks() {
+      PagedIterable<PublicIpBlock> ipBlockList = 
api.getNetworkApi().listPublicIPv4AddressBlocks(networkDomainId);
+      assertTrue(!ipBlockList.isEmpty());
+      assertEquals(ipBlockList.last().get().first().get().size(), 2);
+      assertEquals(ipBlockList.last().get().first().get().networkDomainId(), 
networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testAddPublicIPv4Block")
+   public void testGetPublicIPv4AddressBlocks() {
+      publicIpBlock = 
api.getNetworkApi().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNotNull(publicIpBlock);
+      assertEquals(publicIpBlock.size(), 2);
+      assertEquals(publicIpBlock.networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testGetPublicIPv4AddressBlocks")
+   public void testCreateNatRule() {
+      natRuleId = api.getNetworkApi()
+            .createNatRule(networkDomainId, PREPARED_PRIVATE_IPV4_ADDRESS, 
publicIpBlock.baseIp());
+      assertNotNull(natRuleId);
+   }
+
+   @Test(dependsOnMethods = "testCreateNatRule")
+   public void testListNatRules() {
+      PagedIterable<NatRule> natRulesList = 
api.getNetworkApi().listNatRules(networkDomainId);
+      assertTrue(!natRulesList.isEmpty());
+      assertEquals(natRulesList.last().get().first().get().networkDomainId(), 
networkDomainId);
+   }
+
+   @Test(dependsOnMethods = { "testCreateNatRule", "testListNatRules" })
+   public void testGetNatRule() {
+      NatRule natRule = api.getNetworkApi().getNatRule(natRuleId);
+      assertNotNull(natRule);
+      assertEquals(natRule.networkDomainId(), networkDomainId);
+   }
+
+   @Test(dependsOnMethods = "testGetNatRule", alwaysRun = true)
+   public void testDeleteNatRule() {
+      api.getNetworkApi().deleteNatRule(natRuleId);
+      NatRule natRule = api.getNetworkApi().getNatRule(natRuleId);
+      assertNull(natRule);
+   }
+
+   @Test(dependsOnMethods = { "testDeleteNatRule" })
+   public void testRemovePublicIpBlock() {
+      api.getNetworkApi().removePublicIpBlock(publicIpv4BlockId);
+      publicIpBlock = 
api.getNetworkApi().getPublicIPv4AddressBlock(publicIpv4BlockId);
+      assertNull(publicIpBlock);
+   }
+
    @Test(dependsOnMethods = "testRebootServer")
    public void testPowerOffServer() {
-      api().powerOffServer(serverId);
+      api.getServerApi().powerOffServer(serverId);
       assertTrue(serverStoppedPredicate.apply(serverId), "server did not power 
off after timeout");
    }
 
    @Test(dependsOnMethods = "testPowerOffServer")
    public void testStartServer() {
-      api().startServer(serverId);
+      api.getServerApi().startServer(serverId);
       assertTrue(serverStartedPredicate.apply(serverId), "server did not start 
after timeout");
       assertTrue(vmtoolsRunningPredicate.apply(serverId), "server vm tools not 
running after timeout");
    }
 
    @Test(dependsOnMethods = "testStartServer")
    public void testShutdownServer() {
-      api().shutdownServer(serverId);
+      api.getServerApi().shutdownServer(serverId);
       assertTrue(serverStoppedPredicate.apply(serverId), "server did not 
shutdown after timeout");
    }
 
    @Test(dependsOnMethods = "testShutdownServer")
-   public void testCloneServer() {
+   public void testCloneServerToMakeCustomerImage() {
       CloneServerOptions options = 
CloneServerOptions.builder().clusterId("").description("")
             .guestOsCustomization(false).build();
-      cloneImageId = api().cloneServer(serverId, "ServerApiLiveTest-" + 
System.currentTimeMillis(), options);
+      cloneImageId = api.getServerApi()
+            .cloneServer(serverId, "ServerApiLiveTest-" + 
System.currentTimeMillis(), options);
       assertNotNull(cloneImageId);
       assertTrue(serverNormalPredicate.apply(serverId), "server was not NORMAL 
after timeout");
    }
 
+   @Test(dependsOnMethods = "testCloneServerToMakeCustomerImage")
+   public void testListCustomerImages() {
+      FluentIterable<CustomerImage> customerImages = 
api.getServerImageApi().listCustomerImages().concat();
+      assertNotNull(customerImages);
+      assertTrue(customerImages.anyMatch(new Predicate<CustomerImage>() {
+         @Override
+         public boolean apply(CustomerImage input) {
+            return input.id().equals(cloneImageId);
+         }
+      }));
+   }
+
+   @Test(dependsOnMethods = "testCloneServerToMakeCustomerImage")
+   public void testGetCustomerImage() {
+      CustomerImage customerImage = 
api.getServerImageApi().getCustomerImage(cloneImageId);
+      assertNotNull(customerImage);
+   }
+
+   @Test(dependsOnMethods = "testGetCustomerImage")
+   public void testDeleteCustomerImage() {
+      boolean deleted = 
api.getCustomerImageApi().deleteCustomerImage(cloneImageId);
+      assertTrue(deleted);
+      assertTrue(customerImageDeletedPredicate.apply(cloneImageId), "customer 
image was not DELETED after timeout");
+   }
+
    @AfterClass(alwaysRun = true)
-   public void testDeleteServer() {
+   public void testDeleteServerAndNetworking() {
+      if (publicIpBlock != null) {
+         api.getNetworkApi().removePublicIpBlock(publicIpBlock.id());
+      }
       if (serverId != null) {
-         api().deleteServer(serverId);
+         api.getServerApi().deleteServer(serverId);
          assertTrue(serverDeletedPredicate.apply(serverId), "server was not 
DELETED after timeout");
       }
+      if (vlanId != null) {
+         api.getNetworkApi().deleteVlan(vlanId);
+         assertTrue(vlanDeletedPredicate.apply(vlanId), "vlan is not in a 
DELETED state after timeout");
+      }
+      if (networkDomainId != null) {
+         api.getNetworkApi().deleteNetworkDomain(networkDomainId);
+         assertTrue(networkDomainDeletedPredicate.apply(networkDomainId),
+               "network domain is not in a DELETED state after timeout");
+      }
+      if (tagKeyId != null && !tagKeyId.isEmpty()) {
+         api.getTagApi().deleteTagKey(tagKeyId);
+      }
+   }
+
+   private void findOsImage(final String datacenterId) {
+      Optional<OsImage> osImageOptional = api.getServerImageApi()
+            
.listOsImages(DatacenterIdListFilters.Builder.datacenterId(datacenterId)).first();
+      assertTrue(osImageOptional.isPresent(), "unable to find compatible image 
for datacenter");
+      imageId = osImageOptional.get().id();
+   }
+
+   private void deployVlan() {
+      vlanId = api.getNetworkApi()
+            .deployVlan(networkDomainId, 
ServerApiLiveTest.class.getSimpleName() + new Date().getTime(),
+                  ServerApiLiveTest.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");
+   }
+
+   private String deployNetworkDomain() {
+      String networkDomainName = ServerApiLiveTest.class.getSimpleName() + new 
Date().getTime();
+      final String datacenterId = datacenters.iterator().next();
+      networkDomainId = api.getNetworkApi().deployNetworkDomain(datacenterId, 
networkDomainName,
+            ServerApiLiveTest.class.getSimpleName() + new Date().getTime() + 
"description", "ESSENTIALS");
+      assertNotNull(networkDomainId);
+      assertTrue(networkDomainNormalPredicate.apply(networkDomainId),
+            "network domain is not in a NORMAL state after timeout");
+      return datacenterId;
    }
 
-   private ServerApi api() {
-      return api.getServerApi();
+   private String createTagKey() {
+      String tagKeyName = "jcloudsTagKeyName" + System.currentTimeMillis();
+      String tagKeyId = api.getTagApi()
+            .createTagKey(tagKeyName, "jcloudsTagKeyDescription", 
Boolean.TRUE, Boolean.FALSE);
+      assertNotNull(tagKeyId);
+      return tagKeyId;
    }
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 4d004e9..02ab7ce 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
@@ -18,7 +18,6 @@ package org.jclouds.dimensiondata.cloudcontrol.features;
 
 import com.google.common.collect.FluentIterable;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.dimensiondata.cloudcontrol.domain.CustomerImage;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OsImage;
 import 
org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.testng.annotations.Test;
@@ -51,28 +50,6 @@ public class ServerImageApiLiveTest extends 
BaseDimensionDataCloudControlApiLive
       assertNotNull(osImage);
    }
 
-   @Test
-   public void testListCustomerImages() {
-      FluentIterable<CustomerImage> customerImages = getCustomerImages();
-      assertNotNull(customerImages);
-      for (CustomerImage customerImage : customerImages) {
-         assertNotNull(customerImage);
-      }
-   }
-
-   @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);
-      return customerImages;
-   }
-
    private ServerImageApi api() {
       return api.getServerImageApi();
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
index e8c5052..f7387cd 100644
--- 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
+++ 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/features/TagApiLiveTest.java
@@ -19,17 +19,12 @@ package org.jclouds.dimensiondata.cloudcontrol.features;
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.dimensiondata.cloudcontrol.domain.Tag;
-import org.jclouds.dimensiondata.cloudcontrol.domain.TagInfo;
 import org.jclouds.dimensiondata.cloudcontrol.domain.TagKey;
 import 
org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlApiLiveTest;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.Collections;
-
-import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.AssertJUnit.assertEquals;
@@ -39,27 +34,18 @@ public class TagApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest {
 
    private String tagKeyId;
    private String tagKeyName;
-   private String assetType = "SERVER";
 
    @BeforeClass
    public void setup() {
       super.setup();
       createTagKeyIfNotExist();
-      applyTagToAsset();
    }
 
-   private void applyTagToAsset() {
-      if (tagKeyId != null) {
-         api().applyTags(SERVER_ID, assetType, 
Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
-      }
-   }
-
-   private String createTagKey() {
+   private void createTagKey() {
       tagKeyName = "jcloudsTagKeyName" + System.currentTimeMillis();
       tagKeyId = api().createTagKey(tagKeyName, "jcloudsTagKeyDescription", 
Boolean.TRUE, Boolean.FALSE);
       assertNotNull(tagKeyId);
       assertTagKeyExistsAndIsValid(tagKeyId, tagKeyName, 
"jcloudsTagKeyDescription", Boolean.TRUE, Boolean.FALSE);
-      return tagKeyId;
    }
 
    @Test
@@ -87,33 +73,6 @@ public class TagApiLiveTest extends 
BaseDimensionDataCloudControlApiLiveTest {
       }
    }
 
-   @Test
-   public void testApplyTags() {
-      api().applyTags(SERVER_ID, assetType, 
Collections.singletonList(TagInfo.create(tagKeyId, "jcloudsValue")));
-   }
-
-   @Test
-   public void testListTags() {
-      PagedIterable<Tag> response = api().listTags();
-      assertTrue(FluentIterable.from(response.concat().toList()).anyMatch(new 
Predicate<Tag>() {
-         @Override
-         public boolean apply(Tag input) {
-            return input.tagKeyId().equals(tagKeyId);
-         }
-      }), String.format("Couldn't find tagKeyId %s in listTags response", 
tagKeyId));
-   }
-
-   @Test(dependsOnMethods = { "testListTags", "testListTagKeys" })
-   public void testRemoveTags() {
-      api().removeTags(SERVER_ID, assetType, 
Collections.singletonList(tagKeyId));
-      
assertFalse(FluentIterable.from(api().listTags().concat().toList()).anyMatch(new
 Predicate<Tag>() {
-         @Override
-         public boolean apply(Tag input) {
-            return input.tagKeyId().equals(tagKeyId);
-         }
-      }));
-   }
-
    private void assertTagKeyExistsAndIsValid(String tagKeyId, String 
tagKeyName, String description,
          boolean valueRequired, boolean displayOnReport) {
       TagKey tagKey = api().tagKeyById(tagKeyId);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 85ce632..fecb404 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,6 +17,7 @@
 package org.jclouds.dimensiondata.cloudcontrol.internal;
 
 import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Injector;
 import com.google.inject.Key;
@@ -30,17 +31,20 @@ 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.location.suppliers.ImplicitRegionIdSupplier;
+import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
 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.Map;
 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.CUSTOMER_IMAGE_DELETED_PREDICATE;
 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;
@@ -58,15 +62,10 @@ public class BaseDimensionDataCloudControlApiLiveTest 
extends BaseApiLiveTest<Di
    private final Set<Module> modules = ImmutableSet.<Module>of(new 
ExecutorServiceModule(sameThreadExecutor()));
    protected Set<String> datacenters;
 
-   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 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 final String SERVER_ID = System.getProperty("serverId", 
"b1c537bb-018c-49ba-beef-e0600e948149");
+   protected static final String DEFAULT_PRIVATE_IPV4_BASE_ADDRESS = 
"10.0.0.0";
+   protected static final Integer DEFAULT_PRIVATE_IPV4_PREFIX_SIZE = 24;
+   protected static final String DEFAULT_PROTOCOL = "TCP";
 
    protected Predicate<String> vlanDeletedPredicate;
    protected Predicate<String> vlanNormalPredicate;
@@ -77,6 +76,7 @@ public class BaseDimensionDataCloudControlApiLiveTest extends 
BaseApiLiveTest<Di
    protected Predicate<String> serverDeletedPredicate;
    protected Predicate<String> serverNormalPredicate;
    protected Predicate<String> vmtoolsRunningPredicate;
+   protected Predicate<String> customerImageDeletedPredicate;
 
    public BaseDimensionDataCloudControlApiLiveTest() {
       provider = "dimensiondata-cloudcontrol";
@@ -89,8 +89,17 @@ public class BaseDimensionDataCloudControlApiLiveTest 
extends BaseApiLiveTest<Di
       datacenters = getZones();
    }
 
+   //   private Set<String> getZones() {
+   //      return 
ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+   //   }
+
+   // TODO this leads to a warning - WARNING: failed to find key for value 
https://api-na.dimensiondata.com in {au=https://api-au.dimensiondata.com}; 
choosing first: au
+   // would like to improve this.  Currently I override the location config 
using -  -Djclouds.regions=au -Djclouds.region.au.zones=AU9
    private Set<String> getZones() {
-      return ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+      final String region = 
ctx.utils().injector().getInstance(ImplicitRegionIdSupplier.class).get();
+      final Map<String, Supplier<Set<String>>> regionToZoneMap = 
ctx.utils().injector()
+            .getInstance(RegionIdToZoneIdsSupplier.class).get();
+      return regionToZoneMap.get(region).get();
    }
 
    @Override
@@ -124,6 +133,8 @@ public class BaseDimensionDataCloudControlApiLiveTest 
extends BaseApiLiveTest<Di
       }, Names.named(SERVER_NORMAL_PREDICATE)));
       vmtoolsRunningPredicate = injector.getInstance(Key.get(new 
TypeLiteral<Predicate<String>>() {
       }, Names.named(VM_TOOLS_RUNNING_PREDICATE)));
+      customerImageDeletedPredicate = injector.getInstance(Key.get(new 
TypeLiteral<Predicate<String>>() {
+      }, Names.named(CUSTOMER_IMAGE_DELETED_PREDICATE)));
 
       return injector.getInstance(DimensionDataCloudControlApi.class);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/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 72dfd2c..4f11610 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
@@ -81,7 +81,7 @@ public class BaseDimensionDataCloudControlMockTest implements 
IHookable {
       server = new MockWebServer();
       server.play();
       ctx = 
ContextBuilder.newBuilder(DimensionDataCloudControlProviderMetadata.builder().build()).credentials("",
 "")
-            .endpoint(url("/caas/")).modules(modules).overrides(new 
Properties()).build();
+            .endpoint(url("")).modules(modules).overrides(new 
Properties()).build();
       json = ctx.utils().injector().getInstance(Json.class);
       api = ctx.getApi();
       applyAdditionalServerConfig();

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/f7b8c2ca/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
----------------------------------------------------------------------
diff --git 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
index 7b8e0ae..e9f1f8d 100644
--- 
a/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
+++ 
b/dimensiondata/src/test/java/org/jclouds/dimensiondata/cloudcontrol/parse/CustomerImagesParseTest.java
@@ -26,6 +26,7 @@ import org.jclouds.dimensiondata.cloudcontrol.domain.Disk;
 import org.jclouds.dimensiondata.cloudcontrol.domain.Guest;
 import org.jclouds.dimensiondata.cloudcontrol.domain.ImageNic;
 import org.jclouds.dimensiondata.cloudcontrol.domain.OperatingSystem;
+import org.jclouds.dimensiondata.cloudcontrol.domain.State;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VirtualHardware;
 import org.jclouds.dimensiondata.cloudcontrol.domain.VmTools;
 import 
org.jclouds.dimensiondata.cloudcontrol.internal.BaseDimensionDataCloudControlParseTest;
@@ -52,7 +53,7 @@ public class CustomerImagesParseTest extends 
BaseDimensionDataCloudControlParseT
                   
.of(Disk.builder().id("1bddd4ed-67dc-4e5e-a0d5-b5a6c012ec14").scsiId(0).sizeGb(50)
                         .speed("HIGHPERFORMANCE").build()))
             .createTime(new 
SimpleDateFormatDateService().iso8601DateParse("2016-07-17T23:53:48.000Z"))
-            
.datacenterId("QA1_N2_VMWARE_1").state("FAILED_ADD").guest(Guest.builder().operatingSystem(
+            
.datacenterId("QA1_N2_VMWARE_1").state(State.FAILED_ADD).guest(Guest.builder().operatingSystem(
                   
OperatingSystem.builder().id("WIN2012DC64").displayName("WIN2012DC/64").family("WINDOWS").build())
                   
.vmTools(VmTools.builder().versionStatus(VmTools.VersionStatus.CURRENT)
                         
.runningStatus(VmTools.RunningStatus.NOT_RUNNING).apiVersion(9354)

Reply via email to