JCLOUDS-993 - Add missing parameters to `VirtualMachineApi` - `serviceOfferingId` at `#changeServiceForVirtualMachine` - `options` of type `UpdateVirtualMachineOptions` at `#updateVirtualMachine`
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/9be7339c Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/9be7339c Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/9be7339c Branch: refs/heads/master Commit: 9be7339c3204b6f22aac4ba2ed53b44b8a9706b5 Parents: 89f8184 Author: Irmo Manie <[email protected]> Authored: Tue Sep 1 11:35:44 2015 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Sun Sep 6 23:59:15 2015 +0200 ---------------------------------------------------------------------- .../cloudstack/features/VirtualMachineApi.java | 9 +- .../options/UpdateVirtualMachineOptions.java | 130 +++++++++++++++++++ .../features/VirtualMachineApiLiveTest.java | 10 ++ .../features/VirtualMachineApiTest.java | 26 +++- 4 files changed, 167 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/9be7339c/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineApi.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineApi.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineApi.java index 413bfc5..f98ee9d 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineApi.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineApi.java @@ -32,6 +32,7 @@ import org.jclouds.cloudstack.filters.AuthenticationFilter; import org.jclouds.cloudstack.options.AssignVirtualMachineOptions; import org.jclouds.cloudstack.options.DeployVirtualMachineOptions; import org.jclouds.cloudstack.options.ListVirtualMachinesOptions; +import org.jclouds.cloudstack.options.UpdateVirtualMachineOptions; import org.jclouds.cloudstack.options.StopVirtualMachineOptions; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.OnlyElement; @@ -198,6 +199,8 @@ public interface VirtualMachineApi { * * @param id * The ID of the virtual machine + * @param serviceOfferingId + * The service offering ID to apply to the virtual machine * @return job id related to destroying the VM */ @Named("changeServiceForVirtualMachine") @@ -205,7 +208,8 @@ public interface VirtualMachineApi { @QueryParams(keys = "command", values = "changeServiceForVirtualMachine") @SelectJson("jobid") @Consumes(MediaType.APPLICATION_JSON) - String changeServiceForVirtualMachine(@QueryParam("id") String id); + String changeServiceForVirtualMachine(@QueryParam("id") String id, + @QueryParam("serviceofferingid") String serviceOfferingId); /** * Updates parameters of a virtual machine. @@ -219,7 +223,8 @@ public interface VirtualMachineApi { @QueryParams(keys = "command", values = "updateVirtualMachine") @SelectJson("jobid") @Consumes(MediaType.APPLICATION_JSON) - String updateVirtualMachine(@QueryParam("id") String id); + String updateVirtualMachine(@QueryParam("id") String id, + UpdateVirtualMachineOptions options); /** * Destroys a virtual machine. Once destroyed, only the administrator can http://git-wip-us.apache.org/repos/asf/jclouds/blob/9be7339c/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateVirtualMachineOptions.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateVirtualMachineOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateVirtualMachineOptions.java new file mode 100644 index 0000000..591a6a3 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateVirtualMachineOptions.java @@ -0,0 +1,130 @@ +/* + * 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.cloudstack.options; + +import com.google.common.collect.ImmutableSet; +import org.jclouds.http.options.BaseHttpRequestOptions; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.io.BaseEncoding.base64; + +/** + * Options for updating virtual machines. + * + * @see <a + * href="http://download.cloud.com/releases/3.0.3/api_3.0.3/root_admin/updateVirtualMachine.html" + * /> + */ +public class UpdateVirtualMachineOptions extends BaseHttpRequestOptions { + + public static final UpdateVirtualMachineOptions NONE = new UpdateVirtualMachineOptions(); + + /** + * sets the displayName - just for display purposes. We don't pass this + * parameter to the backend. + * + * @param displayName an optional user generated name for the virtual machine + */ + public UpdateVirtualMachineOptions displayName(String displayName) { + this.queryParameters.replaceValues("displayname", ImmutableSet.of(displayName)); + return this; + } + + /** + * @param group an optional group for the virtual machine + */ + public UpdateVirtualMachineOptions group(String group) { + this.queryParameters.replaceValues("group", ImmutableSet.of(group)); + return this; + } + + /** + * @param haEnable true if high-availability is enabled for the virtual machine, false otherwise + */ + public UpdateVirtualMachineOptions haEnable(boolean haEnable) { + this.queryParameters.replaceValues("haenable", ImmutableSet.of(String.valueOf(haEnable))); + return this; + } + + /** + * @param osTypeId the ID of the OS type that best represents this VM. + */ + public UpdateVirtualMachineOptions osTypeId(String osTypeId) { + this.queryParameters.replaceValues("ostypeid", ImmutableSet.of(String.valueOf(osTypeId))); + return this; + } + + /** + * @param unencodedData an optional binary data that can be sent to the virtual machine + * upon a successful deployment. This binary data must be base64 + * encoded before adding it to the request. Currently only HTTP GET + * is supported. Using HTTP GET (via querystring), you can send up + * to 2KB of data after base64 encoding. + */ + public UpdateVirtualMachineOptions userData(byte[] unencodedData) { + int length = checkNotNull(unencodedData, "unencodedData").length; + checkArgument(length > 0, "userData cannot be empty"); + checkArgument(length <= 2 * 1024, "userData cannot be larger than 2kb"); + this.queryParameters.replaceValues("userdata", ImmutableSet.of(base64().encode(unencodedData))); + return this; + } + + + public static class Builder { + + /** + * @see UpdateVirtualMachineOptions#displayName + */ + public static UpdateVirtualMachineOptions displayName(String displayName) { + UpdateVirtualMachineOptions options = new UpdateVirtualMachineOptions(); + return options.displayName(displayName); + } + + /** + * @see UpdateVirtualMachineOptions#group + */ + public static UpdateVirtualMachineOptions group(String group) { + UpdateVirtualMachineOptions options = new UpdateVirtualMachineOptions(); + return options.group(group); + } + + /** + * @see UpdateVirtualMachineOptions#haEnable + */ + public static UpdateVirtualMachineOptions haEnable(boolean haEnable) { + UpdateVirtualMachineOptions options = new UpdateVirtualMachineOptions(); + return options.haEnable(haEnable); + } + + /** + * @see UpdateVirtualMachineOptions#osTypeId + */ + public static UpdateVirtualMachineOptions osTypeId(String osTypeId) { + UpdateVirtualMachineOptions options = new UpdateVirtualMachineOptions(); + return options.osTypeId(osTypeId); + } + + /** + * @see UpdateVirtualMachineOptions#userData + */ + public static UpdateVirtualMachineOptions userData(byte[] unencodedData) { + UpdateVirtualMachineOptions options = new UpdateVirtualMachineOptions(); + return options.userData(unencodedData); + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/9be7339c/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiLiveTest.java index e7c60b0..1b33bb5 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiLiveTest.java @@ -46,6 +46,7 @@ import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.internal.BaseCloudStackApiLiveTest; import org.jclouds.cloudstack.options.CreateNetworkOptions; import org.jclouds.cloudstack.options.DeployVirtualMachineOptions; +import org.jclouds.cloudstack.options.UpdateVirtualMachineOptions; import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions; import org.jclouds.cloudstack.options.ListNetworksOptions; import org.jclouds.cloudstack.options.ListTemplatesOptions; @@ -321,6 +322,15 @@ public class VirtualMachineApiLiveTest extends BaseCloudStackApiLiveTest { assertEquals(vm.getState(), VirtualMachine.State.RUNNING); } + @Test(dependsOnMethods = "testCreateVirtualMachine") + public void testVirtualMachineUpdate() throws Exception { + UpdateVirtualMachineOptions options = UpdateVirtualMachineOptions.Builder.displayName("updated-name"); + String job = client.getVirtualMachineApi().updateVirtualMachine(vm.getId(), options); + assertTrue(jobComplete.apply(job)); + vm = client.getVirtualMachineApi().getVirtualMachine(vm.getId()); + assertEquals(vm.getDisplayName(), "updated-name"); + } + @AfterGroups(groups = "live") @Override protected void tearDownContext() { http://git-wip-us.apache.org/repos/asf/jclouds/blob/9be7339c/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiTest.java ---------------------------------------------------------------------- diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiTest.java index c06c08b..e956074 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineApiTest.java @@ -19,9 +19,12 @@ package org.jclouds.cloudstack.features; import static org.jclouds.reflect.Reflection2.method; import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.Charset; import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.cloudstack.options.UpdateVirtualMachineOptions; import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions; import org.jclouds.cloudstack.internal.BaseCloudStackApiTest; import org.jclouds.cloudstack.options.AssignVirtualMachineOptions; @@ -35,6 +38,7 @@ import org.testng.annotations.Test; import com.google.common.base.Functions; import com.google.common.collect.ImmutableList; import com.google.common.reflect.Invokable; +import static com.google.common.io.BaseEncoding.base64; /** * Tests behavior of {@code VirtualMachineApi} */ @@ -187,11 +191,11 @@ public class VirtualMachineApiTest extends BaseCloudStackApiTest<VirtualMachineA } public void testChangeServiceForVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { - Invokable<?, ?> method = method(VirtualMachineApi.class, "changeServiceForVirtualMachine", String.class); - GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of(5)); + Invokable<?, ?> method = method(VirtualMachineApi.class, "changeServiceForVirtualMachine", String.class, String.class); + GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of(5, 6)); assertRequestLineEquals(httpRequest, - "GET http://localhost:8080/client/api?response=json&command=changeServiceForVirtualMachine&id=5 HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=changeServiceForVirtualMachine&id=5&serviceofferingid=6 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); @@ -204,11 +208,21 @@ public class VirtualMachineApiTest extends BaseCloudStackApiTest<VirtualMachineA } public void testUpdateVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { - Invokable<?, ?> method = method(VirtualMachineApi.class, "updateVirtualMachine", String.class); - GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of(5)); + Invokable<?, ?> method = method(VirtualMachineApi.class, "updateVirtualMachine", String.class, + UpdateVirtualMachineOptions.class); + byte[] unencodedData = "userData".getBytes(Charset.forName("utf-8")); + UpdateVirtualMachineOptions options = UpdateVirtualMachineOptions.Builder + .displayName("disp").group("test").haEnable(true).osTypeId("osid").userData(unencodedData); + GeneratedHttpRequest httpRequest = processor.createRequest(method, ImmutableList.<Object> of("5", + options)); + + + String base64UrlEncodedData = URLEncoder.encode(base64().encode(unencodedData), "utf-8"); assertRequestLineEquals(httpRequest, - "GET http://localhost:8080/client/api?response=json&command=updateVirtualMachine&id=5 HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=updateVirtualMachine" + + "&id=5&displayname=disp&group=test&haenable=true&ostypeid=osid&userdata=" + + base64UrlEncodedData + " HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false);
