nacx requested changes on this pull request.

Thanks, @trevorflanagan! Apologies for the delay in the review. We've been 
quite busy with the 2.0.2 release.

>  
-   public abstract int sizeGb();
+   @Nullable
+   public abstract Integer sizeGb();

Can this field have decimals? (Just asking; I'm not familiar with the API).

> +         @Nullable @PayloadParam("disk") List<Disk> disks, @Nullable 
> CreateServerOptions options);
+
+   @Named("server:delete")
+   @POST
+   @Path("/deleteServer")
+   @Produces(MediaType.APPLICATION_JSON)
+   @Fallback(Fallbacks.VoidOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   void deleteServer(@PayloadParam("id") String id);
+
+   @Named("server:powerOff")
+   @POST
+   @Path("/powerOffServer")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindToJsonPayload.class)
+   @Fallback(Fallbacks.VoidOnNotFoundOr404.class)

In state change operations I think it would be better to fail if the server 
does not exist. Otherwise, users won't be able to differentiate a failed 
execution than a succeeded one. The use case here is different than in get 
operations or delete (where the purpose is to have the server gone). Let's 
remove the 404 fallbacks from all state change operations.


> + * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.dimensiondata.cloudcontrol.predicates;
+
+import com.google.common.base.Predicate;
+import org.jclouds.dimensiondata.cloudcontrol.domain.Server;
+import org.jclouds.dimensiondata.cloudcontrol.features.ServerApi;
+import org.jclouds.logging.Logger;
+
+import javax.annotation.Resource;
+import java.text.MessageFormat;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class ServerStatus implements Predicate<String> {

Does this duplicate the `ServerState` class?

> +   protected Logger logger = Logger.NULL;
+   private final ServerApi api;
+
+   public VMToolsRunningStatus(ServerApi api) {
+      this.api = api;
+   }
+
+   @Override
+   public boolean apply(String serverId) {
+      checkNotNull(serverId, "serverId");
+      logger.trace("looking for state on Server %s", serverId);
+      final Server server = api.getServer(serverId);
+      if (server == null) {
+         throw new IllegalStateException(MessageFormat.format("Server {0} is 
not found", serverId));
+      }
+      return 
server.guest().vmTools().runningStatus().equals(VmTools.RunningStatus.RUNNING);

The `vmTools` field is nullable. Protect this against a NPE.

>           throw new IllegalStateException(message);
       }
    }
 
+   public static void waitForVmToolsRunning(ServerApi api, String serverId, 
long timeoutMillis, String message) {
+      boolean vmwareToolsRunning = retry(new VMToolsRunningStatus(api), 
timeoutMillis).apply(serverId);
+      if (!vmwareToolsRunning) {
+         throw new IllegalStateException(message);
+      }
+   }

Instead of having a static class with these accessors, consider configuring all 
these predicates as injectable predicates. this makes it easier to get them 
injected in the jclouds classes (such as the compute service when implemented), 
and also allows users to configure the timeout values, etc, via properties.
You can have a look at [the digitalocean2 
provider](https://github.com/jclouds/jclouds/blob/master/providers/digitalocean2/src/main/java/org/jclouds/digitalocean2/compute/config/DigitalOcean2ComputeServiceContextModule.java#L100-L216)
 for an example.

> +   @Test
+   public void testDeployAndStartServer() {
+      Boolean started = Boolean.TRUE;
+      NetworkInfo networkInfo = NetworkInfo
+            .create(NETWORK_DOMAIN_ID, NIC.builder().vlanId(VLAN_ID).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);
+      assertNotNull(serverId);
+      waitForServerStatus(api(), serverId, true, true, 30 * 60 * 1000, 
"Error");
+      waitForServerState(api(), serverId, State.NORMAL, 30 * 60 * 1000, 
"Error");
+   }
+
+   @Test(dependsOnMethods = "testDeployAndStartServer")
+   public void testReconfigureServer() {
+      api().reconfigureServer(serverId, 4, CpuSpeed.HIGHPERFORMANCE.name(), 1);
+      waitForServerState(api(), serverId, State.PENDING_CHANGE, 30 * 60 * 
1000, "Error");

Is it possible that the reconfigure operation is fast enough that we don't 
actually see this state? Does it really make sense to wait for intermediate 
states?

> +   @Test(dependsOnMethods = "testStartServer")
+   public void testShutdownServer() {
+      api().shutdownServer(serverId);
+      waitForServerStatus(api(), serverId, false, true, 30 * 60 * 1000, 
"Error");
+   }
+
+   @Test(dependsOnMethods = "testShutdownServer")
+   public void testCloneServer() {
+      CloneServerOptions options = 
CloneServerOptions.builder().clusterId("").description("")
+            .guestOsCustomization(false).build();
+      cloneImageId = api().cloneServer(serverId, "ServerApiLiveTest-" + 
System.currentTimeMillis(), options);
+      assertNotNull(cloneImageId);
+      waitForServerState(api(), serverId, State.NORMAL, 30 * 60 * 1000, 
"Error");
+   }
+
+   @AfterClass

Annotate with `alwaysRun = true` to let it run even if tests fail.

> +      }
+   }
+
+   public void testGetServer() throws Exception {
+      server.enqueue(jsonResponse("/server.json"));
+      Server found = serverApi().getServer("12345");
+      assertSent(GET, 
"/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/server/12345");
+      assertNotNull(found);
+      assertNotNull(found.guest().vmTools());
+   }
+
+   public void testGetServer_404() throws Exception {
+      server.enqueue(response404());
+      serverApi().getServer("12345");
+      assertSent(GET, 
"/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/server/12345");
+   }

Duplicates the `testGetServerReturnsResourceNotFound` test?

> +   }
+
+   public void testListServers() throws Exception {
+      server.enqueue(jsonResponse("/servers.json"));
+      List<Server> servers = serverApi().listServers().concat().toList();
+      Uris.UriBuilder uriBuilder = 
Uris.uriBuilder("/caas/2.4/6ac1e746-b1ea-4da5-a24e-caf1a978789d/server/server");
+      Set<String> zones = 
ctx.utils().injector().getInstance(ZoneIdsSupplier.class).get();
+      for (String zone : zones) {
+         uriBuilder.addQuery("datacenterId", zone);
+      }
+      assertSent(GET, uriBuilder.toString());
+      assertEquals(servers.size(), 1);
+      for (Server s : servers) {
+         assertNotNull(s);
+      }
+   }

Add a test for the list method when the response is a 404.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/400#pullrequestreview-50242855

Reply via email to