Merge pull request #1465 from aplowe/1.6.x
cloudstack: adding support for create volume from a custom disk offering
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeAsyncClient.java
index e9d9bd7..56d4c1d 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeAsyncClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeAsyncClient.java
@@ -90,6 +90,18 @@
@QueryParam("zoneid") String zoneId);
/**
+ * @see VolumeClient#createVolumeFromCustomDiskOfferingInZone(String, String, String, int)
+ */
+ @GET
+ @QueryParams(keys = "command", values = "createVolume")
+ @Unwrap
+ @Consumes(MediaType.APPLICATION_JSON)
+ ListenableFuture<AsyncCreateResponse> createVolumeFromCustomDiskOfferingInZone(@QueryParam("name") String name,
+ @QueryParam("diskofferingid") String diskOfferingId,
+ @QueryParam("zoneid") String zoneId,
+ @QueryParam("size") int size);
+
+ /**
* @see VolumeClient#createVolumeFromSnapshotInZone(String, String, String)
*/
@Named("createVolume")
diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeClient.java
index 73d845a..744bc3c 100644
--- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeClient.java
+++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VolumeClient.java
@@ -42,6 +42,18 @@
*/
AsyncCreateResponse createVolumeFromDiskOfferingInZone(String name, String diskOfferingId, String zoneId);
+
+ /**
+ * Create a volume with given name, size and diskOfferingId
+ *
+ * @param name name of the volume
+ * @param diskOfferingId the ID of the disk offering (the offering should have the custom disk size flag set)
+ * @param zoneId the ID of the availability zone
+ * @param size the size of volume required (in GB)
+ * @return AsyncCreateResponse job response used to track creation
+ */
+ AsyncCreateResponse createVolumeFromCustomDiskOfferingInZone(String name, String diskOfferingId, String zoneId, int size);
+
/**
* Create a volume with given name and snapshotId
*
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientExpectTest.java
new file mode 100644
index 0000000..e930033
--- /dev/null
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientExpectTest.java
@@ -0,0 +1,65 @@
+/**
+* Licensed to jclouds, Inc. (jclouds) under one or more
+* contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. jclouds 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.cloudstack.features;
+
+import org.jclouds.cloudstack.CloudStackApiMetadata;
+import org.jclouds.cloudstack.CloudStackContext;
+import org.jclouds.cloudstack.domain.AsyncCreateResponse;
+import org.jclouds.cloudstack.internal.BaseCloudStackExpectTest;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import java.net.URI;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+
+import static org.testng.Assert.assertNotNull;
+
+/**
+* Test the CloudStack VolumeClient
+*
+* @author Adam Lowe
+*/
+@Test(groups = "unit", testName = "VolumeClientExpectTest")
+public class VolumeClientExpectTest extends BaseCloudStackExpectTest<VolumeClient> {
+
+ public void testCreateVolumeFromCustomDiskOffering() throws NoSuchAlgorithmException, CertificateException {
+ VolumeClient client = requestSendsResponse(
+ HttpRequest.builder()
+ .method("GET")
+ .endpoint(
+ URI.create("http://localhost:8080/client/api?response=json&" +
+ "command=createVolume&name=VolumeClientExpectTest-jclouds-volume&diskofferingid=0473f5dd-bca5-4af4-a9b6-db9e8a88a2f6&zoneid=6f9a2921-b22a-4149-8b71-6ffc275a2177&size=1&apiKey=identity&signature=Y4%2BmdvhS/jlKRNSJ3nQqrjwg1CY%3D"))
+ .addHeader("Accept", "application/json")
+ .build(),
+ HttpResponse.builder()
+ .statusCode(200)
+ .payload(payloadFromResource("/queryasyncjobresultresponse-createvolume.json"))
+ .build());
+
+ AsyncCreateResponse response = client.createVolumeFromCustomDiskOfferingInZone("VolumeClientExpectTest-jclouds-volume", "0473f5dd-bca5-4af4-a9b6-db9e8a88a2f6", "6f9a2921-b22a-4149-8b71-6ffc275a2177", 1);
+ assertNotNull(response);
+ }
+
+ @Override
+ protected VolumeClient clientFrom(CloudStackContext context) {
+ return context.unwrap(CloudStackApiMetadata.CONTEXT_TOKEN).getApi().getVolumeClient();
+ }
+}
diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientLiveTest.java
index 258a8d5..0620987 100644
--- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientLiveTest.java
+++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VolumeClientLiveTest.java
@@ -164,6 +164,33 @@
client.getVolumeClient().deleteVolume(volume.getId());
}
+ /** Test requires a custom disk offering to be available */
+ public void testCreateVolumeFromCustomDiskOffering() {
+ final int size = 1;
+ DiskOffering offering = null;
+ for (DiskOffering candidate : client.getOfferingClient().listDiskOfferings()) {
+ if (candidate.isCustomized()) {
+ offering = candidate;
+ break;
+ }
+ }
+
+ assertNotNull("No custom disk offering found!", offering);
+
+ AsyncCreateResponse job = client.getVolumeClient().createVolumeFromCustomDiskOfferingInZone(
+ prefix + "-jclouds-volume", offering.getId(), zoneId, size);
+ assertTrue(jobComplete.apply(job.getJobId()));
+ logger.info("created volume "+job.getId());
+
+ Volume volume = findVolumeWithId(job.getId());
+ try {
+ checkVolume(volume);
+ assertEquals(volume.getSize(), size * 1024 * 1024 * 1024);
+ } finally {
+ client.getVolumeClient().deleteVolume(volume.getId());
+ }
+ }
+
/** test requires that a VM exist */
public void testCreateVolumeFromDiskofferingInZoneAndAttachVolumeToVirtualMachineAndDetachAndDelete() {
logger.info("testCreateVolumeFromDiskofferingInZoneAndAttachVolumeToVirtualMachineAndDetachAndDelete");
diff --git a/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-createvolume.json b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-createvolume.json
new file mode 100644
index 0000000..31f31d0
--- /dev/null
+++ b/apis/cloudstack/src/test/resources/queryasyncjobresultresponse-createvolume.json
@@ -0,0 +1,36 @@
+{
+ "queryasyncjobresultresponse" :
+ {"accountid":"43e3d66f-c8a3-43b2-a3d0-3bbc2416da14",
+ "userid":"99458e63-725b-48ec-aedc-f8ccc11f5231",
+ "cmd":"com.cloud.api.commands.CreateVolumeCmd",
+ "jobstatus":1,
+ "jobprocstatus":0,
+ "jobresultcode":0,
+ "jobresulttype":"object",
+ "jobresult":{
+ "volume":{
+ "id":"f947c7b3-e079-4e7d-aacc-1509d1ae387a",
+ "name":"VolumeClientExpectTest-jclouds-volume",
+ "zoneid":"6f9a2921-b22a-4149-8b71-6ffc275a2177",
+ "zonename":"Basic1",
+ "type":"DATADISK",
+ "size":1073741824,
+ "created":"2013-02-05T13:41:14+0200",
+ "state":"Allocated",
+ "account":"admin",
+ "domainid":"99f4159b-c698-4bd9-b8c5-5ac462f101eb",
+ "domain":"ROOT",
+ "storagetype":"shared",
+ "hypervisor":"None",
+ "diskofferingid":"0473f5dd-bca5-4af4-a9b6-db9e8a88a2f6",
+ "diskofferingname":"Custom",
+ "diskofferingdisplaytext":"Custom Disk",
+ "storage":"none","destroyed":false,
+ "isextractable":true,
+ "tags":[]
+ }
+ },
+ "created":"2013-02-05T13:41:14+0200",
+ "jobid":"4ec82395-365a-4dad-8bd7-238c4f388702"
+ }
+}