diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java index 9fde927dcb..2f7da209bf 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostAsyncClient.java @@ -28,6 +28,7 @@ import org.jclouds.cloudstack.options.AddSecondaryStorageOptions; import org.jclouds.cloudstack.options.DeleteHostOptions; import org.jclouds.cloudstack.options.ListClustersOptions; import org.jclouds.cloudstack.options.ListHostsOptions; +import org.jclouds.cloudstack.options.UpdateClusterOptions; import org.jclouds.cloudstack.options.UpdateHostOptions; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.QueryParams; @@ -190,4 +191,17 @@ public interface GlobalHostAsyncClient { @SelectJson("cluster") @Consumes(MediaType.APPLICATION_JSON) ListenableFuture addCluster(@QueryParam("zoneid") long zoneId, @QueryParam("clustername") String clusterName, @QueryParam("clustertype") Host.ClusterType clusterType, @QueryParam("hypervisor") String hypervisor, AddClusterOptions... options); + + /** + * Updates an existing cluster. + * + * @param clusterId the ID of the cluster + * @param options optional arguments + * @return the modified cluster + */ + @GET + @QueryParams(keys = "command", values = "updateCluster") + @SelectJson("cluster") + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture updateCluster(@QueryParam("id") long clusterId, UpdateClusterOptions... options); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java index 295b2d968e..24cb3e9000 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalHostClient.java @@ -26,6 +26,7 @@ import org.jclouds.cloudstack.options.AddSecondaryStorageOptions; import org.jclouds.cloudstack.options.DeleteHostOptions; import org.jclouds.cloudstack.options.ListClustersOptions; import org.jclouds.cloudstack.options.ListHostsOptions; +import org.jclouds.cloudstack.options.UpdateClusterOptions; import org.jclouds.cloudstack.options.UpdateHostOptions; import org.jclouds.concurrent.Timeout; @@ -144,4 +145,13 @@ public interface GlobalHostClient { * @return the new cluster. */ Cluster addCluster(long zoneId, String clusterName, Host.ClusterType clusterType, String hypervisor, AddClusterOptions... options); + + /** + * Updates an existing cluster. + * + * @param clusterId the ID of the cluster + * @param options optional arguments + * @return the modified cluster + */ + Cluster updateCluster(long clusterId, UpdateClusterOptions... options); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateClusterOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateClusterOptions.java new file mode 100644 index 0000000000..e02fcbdb51 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/UpdateClusterOptions.java @@ -0,0 +1,113 @@ +/** + * 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.options; + +import com.google.common.collect.ImmutableSet; +import org.jclouds.cloudstack.domain.Cluster; +import org.jclouds.cloudstack.domain.Host; +import org.jclouds.http.options.BaseHttpRequestOptions; + +/** + * Options for the GlobalHostClient.updateCluster() API call. + * + * @author Richard Downer + */ +public class UpdateClusterOptions extends BaseHttpRequestOptions { + + public static final UpdateClusterOptions NONE = new UpdateClusterOptions(); + + /** + * @param allocationState Allocation state of this cluster for allocation of new resources + */ + public UpdateClusterOptions allocationState(Host.AllocationState allocationState) { + this.queryParameters.replaceValues("allocationstate", ImmutableSet.of(allocationState.toString())); + return this; + } + + /** + * @param clusterName the cluster name + */ + public UpdateClusterOptions clusterName(String clusterName) { + this.queryParameters.replaceValues("clustername", ImmutableSet.of(clusterName)); + return this; + } + + /** + * @param clusterType type of the cluster + */ + public UpdateClusterOptions clusterType(Host.ClusterType clusterType) { + this.queryParameters.replaceValues("clustertype", ImmutableSet.of(clusterType.toString())); + return this; + } + + /** + * @param hypervisor hypervisor type of the cluster + */ + public UpdateClusterOptions hypervisor(String hypervisor) { + this.queryParameters.replaceValues("hypervisor", ImmutableSet.of(hypervisor)); + return this; + } + + /** + * @param managedState whether this cluster is managed by cloudstack + */ + public UpdateClusterOptions managedState(Cluster.ManagedState managedState) { + this.queryParameters.replaceValues("managedstate", ImmutableSet.of(managedState.toString())); + return this; + } + + public static class Builder { + + /** + * @param allocationState Allocation state of this cluster for allocation of new resources + */ + public static UpdateClusterOptions allocationState(Host.AllocationState allocationState) { + return new UpdateClusterOptions().allocationState(allocationState); + } + + /** + * @param clusterName the cluster name + */ + public static UpdateClusterOptions clusterName(String clusterName) { + return new UpdateClusterOptions().clusterName(clusterName); + } + + /** + * @param clusterType type of the cluster + */ + public static UpdateClusterOptions clusterType(Host.ClusterType clusterType) { + return new UpdateClusterOptions().clusterType(clusterType); + } + + /** + * @param hypervisor hypervisor type of the cluster + */ + public static UpdateClusterOptions hypervisor(String hypervisor) { + return new UpdateClusterOptions().hypervisor(hypervisor); + } + + /** + * @param managedState whether this cluster is managed by cloudstack + */ + public static UpdateClusterOptions managedState(Cluster.ManagedState managedState) { + return new UpdateClusterOptions().managedState(managedState); + } + + } +} diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientExpectTest.java index 0a00ec6f65..b4df927fb0 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientExpectTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalHostClientExpectTest.java @@ -29,6 +29,7 @@ import org.jclouds.cloudstack.options.AddClusterOptions; import org.jclouds.cloudstack.options.AddHostOptions; import org.jclouds.cloudstack.options.AddSecondaryStorageOptions; import org.jclouds.cloudstack.options.DeleteHostOptions; +import org.jclouds.cloudstack.options.UpdateClusterOptions; import org.jclouds.cloudstack.options.UpdateHostOptions; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; @@ -284,6 +285,24 @@ public class GlobalHostClientExpectTest extends BaseCloudStackRestClientExpectTe assertEquals(actual, expected); } + @Test + public void testUpdateClusterWhenResponseIs2xx() { + HttpRequest request = HttpRequest.builder() + .method("GET") + .endpoint(URI.create("http://localhost:8080/client/api?response=json&command=updateCluster&id=1&allocationstate=Enabled&clustername=Xen%20Clust%201&clustertype=CloudManaged&hypervisor=XenServer&managedstate=Managed&apiKey=identity&signature=%2FwbuYKwInciSXWkUf05lEfJZShQ%3D")) + .headers(ImmutableMultimap.builder().put("Accept", "application/json").build()) + .build(); + HttpResponse response = HttpResponse.builder() + .payload(payloadFromResource("/updateclusterresponse.json")) + .statusCode(200).build(); + + Cluster expected = Cluster.builder().id(1).name("Xen Clust 1").podId(1).podName("Dev Pod 1").zoneId(1).zoneName("Dev Zone 1").hypervisor("XenServer").clusterType(Host.ClusterType.CLOUD_MANAGED).allocationState(Host.AllocationState.ENABLED).managedState(Cluster.ManagedState.MANAGED).build(); + + Cluster actual = requestSendsResponse(request, response).updateCluster(1, UpdateClusterOptions.Builder.allocationState(Host.AllocationState.ENABLED).clusterName("Xen Clust 1").clusterType(Host.ClusterType.CLOUD_MANAGED).hypervisor("XenServer").managedState(Cluster.ManagedState.MANAGED)); + + assertEquals(actual, expected); + } + private Date makeDate(int year, int month, int date, int hour, int minute, int second, String timeZoneName) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(timeZoneName)); cal.set(Calendar.YEAR, year); diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/UpdateClusterOptionsTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/UpdateClusterOptionsTest.java new file mode 100644 index 0000000000..0cb7db39e1 --- /dev/null +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/UpdateClusterOptionsTest.java @@ -0,0 +1,67 @@ +/** + * 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.options; + +import com.google.common.collect.ImmutableList; +import org.jclouds.cloudstack.domain.Cluster; +import org.jclouds.cloudstack.domain.Host; +import org.testng.annotations.Test; + +import static org.jclouds.cloudstack.options.UpdateClusterOptions.Builder.allocationState; +import static org.testng.Assert.assertEquals; + +/** + * Tests behavior of {@code UpdateClusterOptions} + * + * @author Richard Downer + */ +@Test(groups = "unit") +public class UpdateClusterOptionsTest { + + public void testAllocationState() { + UpdateClusterOptions options = new UpdateClusterOptions().allocationState(Host.AllocationState.ENABLED); + assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("allocationstate")); + } + + public void testAllocationStateStatic() { + UpdateClusterOptions options = allocationState(Host.AllocationState.ENABLED); + assertEquals(ImmutableList.of("Enabled"), options.buildQueryParameters().get("allocationstate")); + } + + public void testClusterName() { + UpdateClusterOptions options = new UpdateClusterOptions().clusterName("My Cluster"); + assertEquals(ImmutableList.of("My Cluster"), options.buildQueryParameters().get("clustername")); + } + + public void testClusterType() { + UpdateClusterOptions options = new UpdateClusterOptions().clusterType(Host.ClusterType.CLOUD_MANAGED); + assertEquals(ImmutableList.of("CloudManaged"), options.buildQueryParameters().get("clustertype")); + } + + public void testHypervisor() { + UpdateClusterOptions options = new UpdateClusterOptions().hypervisor("XenServer"); + assertEquals(ImmutableList.of("XenServer"), options.buildQueryParameters().get("hypervisor")); + } + + public void testManagedState() { + UpdateClusterOptions options = new UpdateClusterOptions().managedState(Cluster.ManagedState.PREPARE_UNMANAGED); + assertEquals(ImmutableList.of("PrepareUnmanaged"), options.buildQueryParameters().get("managedstate")); + } + +} diff --git a/apis/cloudstack/src/test/resources/updateclusterresponse.json b/apis/cloudstack/src/test/resources/updateclusterresponse.json new file mode 100644 index 0000000000..4a03ca3a25 --- /dev/null +++ b/apis/cloudstack/src/test/resources/updateclusterresponse.json @@ -0,0 +1 @@ +{ "updateclusterresponse" : { "cluster" : {"warning":"this test data is fabricated","id":1,"name":"Xen Clust 1","podid":1,"podname":"Dev Pod 1","zoneid":1,"zonename":"Dev Zone 1","hypervisortype":"XenServer","clustertype":"CloudManaged","allocationstate":"Enabled","managedstate":"Managed"} } } \ No newline at end of file