diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerAsyncClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerAsyncClient.java index bc72b03220..533ce738af 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerAsyncClient.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerAsyncClient.java @@ -20,6 +20,7 @@ package org.jclouds.softlayer; import org.jclouds.rest.annotations.Delegate; +import org.jclouds.softlayer.features.DatacenterAsyncClient; import org.jclouds.softlayer.features.VirtualGuestAsyncClient; /** @@ -38,4 +39,9 @@ public interface SoftLayerAsyncClient { @Delegate VirtualGuestAsyncClient getVirtualGuestClient(); + /** + * Provides asynchronous access to Datacenter features. + */ + @Delegate + DatacenterAsyncClient getDatacenterClient(); } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerClient.java index faea8510cf..b69ba34ab2 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerClient.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerClient.java @@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; import org.jclouds.rest.annotations.Delegate; +import org.jclouds.softlayer.features.DatacenterClient; import org.jclouds.softlayer.features.VirtualGuestClient; /** @@ -42,4 +43,9 @@ public interface SoftLayerClient { @Delegate VirtualGuestClient getVirtualGuestClient(); + /** + * Provides synchronous access to Datacenter features. + */ + @Delegate + DatacenterClient getDatacenterClient(); } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/config/SoftLayerRestClientModule.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/config/SoftLayerRestClientModule.java index 2cd212b771..87c7f70b45 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/config/SoftLayerRestClientModule.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/config/SoftLayerRestClientModule.java @@ -34,6 +34,8 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.config.RestClientModule; import org.jclouds.softlayer.SoftLayerAsyncClient; import org.jclouds.softlayer.SoftLayerClient; +import org.jclouds.softlayer.features.DatacenterAsyncClient; +import org.jclouds.softlayer.features.DatacenterClient; import org.jclouds.softlayer.features.VirtualGuestAsyncClient; import org.jclouds.softlayer.features.VirtualGuestClient; import org.jclouds.softlayer.handlers.SoftLayerErrorHandler; @@ -51,6 +53,7 @@ public class SoftLayerRestClientModule extends RestClientModule, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// .put(VirtualGuestClient.class, VirtualGuestAsyncClient.class)// + .put(DatacenterClient.class, DatacenterAsyncClient.class)// .build(); public SoftLayerRestClientModule() { diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Datacenter.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Datacenter.java new file mode 100644 index 0000000000..6716a78836 --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Datacenter.java @@ -0,0 +1,106 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.softlayer.domain; + +/** + * + * @author Adrian Cole + * @see + */ +public class Datacenter implements Comparable { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private long id = -1; + private String name; + private String longName; + + public Builder id(long id) { + this.id = id; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder longName(String longName) { + this.longName = longName; + return this; + } + + public Datacenter build() { + return new Datacenter(id, name, longName); + } + + public static Builder fromDatacenter(Datacenter in) { + return Datacenter.builder().id(in.getId()).name(in.getName()).longName(in.getLongName()); + } + } + + private long id = -1; + private String name; + private String longName; + + // for deserializer + Datacenter() { + + } + + public Datacenter(long id, String name, String longName) { + this.id = id; + this.name = name; + this.longName = longName; + } + + @Override + public int compareTo(Datacenter arg0) { + return new Long(id).compareTo(arg0.getId()); + } + + /** + * @return The unique identifier of a specific location. + */ + public long getId() { + return id; + } + + /** + * @return A short location description. + */ + public String getName() { + return name; + } + + /** + * @return A longer location description. + */ + public String getLongName() { + return longName; + } + + public Builder toBuilder() { + return Builder.fromDatacenter(this); + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterAsyncClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterAsyncClient.java new file mode 100644 index 0000000000..97f60ecf78 --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterAsyncClient.java @@ -0,0 +1,70 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.softlayer.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.softlayer.domain.Datacenter; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to LocationDatacenter via their REST API. + *

+ * + * @see DatacenterClient + * @see + * @author Adrian Cole + */ +@RequestFilters(BasicAuthentication.class) +@Path("/v{jclouds.api-version}") +public interface DatacenterAsyncClient { + + /** + * @see LocationDatacenterClient#listDatacenters + */ + @GET + @Path("/SoftLayer_Location_Datacenter/Datacenters.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listDatacenters(); + + /** + * @see LocationDatacenterClient#getLocationDatacenter + */ + @GET + @Path("/SoftLayer_Location_Datacenter/{id}.json") + @QueryParams(keys = "objectMask", values = "locationAddress") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getDatacenter(@PathParam("id") long id); +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterClient.java new file mode 100644 index 0000000000..f0bf83b987 --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/DatacenterClient.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.softlayer.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.softlayer.domain.Datacenter; + +/** + * Provides synchronous access to LocationDatacenter. + *

+ * + * @see DatacenterAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 4, timeUnit = TimeUnit.SECONDS) +public interface DatacenterClient { + + /** + * + * @return an account's associated datacenter objects. + */ + Set listDatacenters(); + + /** + * + * @param id + * id of the datacenter + * @return datacenter or null if not found + */ + Datacenter getDatacenter(long id); + +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java index cd2ffaef62..58654a4ebc 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestAsyncClient.java @@ -29,9 +29,11 @@ import javax.ws.rs.core.MediaType; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.softlayer.domain.VirtualGuest; import com.google.common.util.concurrent.ListenableFuture; @@ -47,12 +49,14 @@ import com.google.common.util.concurrent.ListenableFuture; @RequestFilters(BasicAuthentication.class) @Path("/v{jclouds.api-version}") public interface VirtualGuestAsyncClient { + public static String GUEST_MASK = "powerState;networkVlans;operatingSystem.passwords;datacenter"; /** * @see VirtualGuestClient#listVirtualGuests */ @GET - @Path("/VirtualGuest_Account/VirtualGuests.json") + @Path("/SoftLayer_Account/VirtualGuests.json") + @QueryParams(keys = "objectMask", values = GUEST_MASK) @Consumes(MediaType.APPLICATION_JSON) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> listVirtualGuests(); @@ -61,8 +65,54 @@ public interface VirtualGuestAsyncClient { * @see VirtualGuestClient#getVirtualGuest */ @GET - @Path("/VirtualGuest_Virtual_Guest/{id}.json") + @Path("/SoftLayer_Virtual_Guest/{id}.json") + @QueryParams(keys = "objectMask", values = GUEST_MASK) @Consumes(MediaType.APPLICATION_JSON) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture getVirtualGuest(@PathParam("id") long id); + + /** + * @see VirtualGuestClient#rebootHardVirtualGuest + */ + @GET + @Path("/SoftLayer_Virtual_Guest/{id}/rebootHard.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture rebootHardVirtualGuest(@PathParam("id") long id); + + /** + * @see VirtualGuestClient#powerOffVirtualGuest + */ + @GET + @Path("/SoftLayer_Virtual_Guest/{id}/powerOff.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture powerOffVirtualGuest(@PathParam("id") long id); + + /** + * @see VirtualGuestClient#powerOnVirtualGuest + */ + @GET + @Path("/SoftLayer_Virtual_Guest/{id}/powerOn.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture powerOnVirtualGuest(@PathParam("id") long id); + + /** + * @see VirtualGuestClient#pauseVirtualGuest + */ + @GET + @Path("/SoftLayer_Virtual_Guest/{id}/pause.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture pauseVirtualGuest(@PathParam("id") long id); + + /** + * @see VirtualGuestClient#resumeVirtualGuest + */ + @GET + @Path("/SoftLayer_Virtual_Guest/{id}/resume.json") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture resumeVirtualGuest(@PathParam("id") long id); } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestClient.java index c5fe226f2d..a391f1f4d8 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestClient.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/VirtualGuestClient.java @@ -50,4 +50,43 @@ public interface VirtualGuestClient { */ VirtualGuest getVirtualGuest(long id); + /** + * hard reboot the guest. + * + * @param id + * id of the virtual guest + */ + void rebootHardVirtualGuest(long id); + + /** + * Power off a guest + * + * @param id + * id of the virtual guest + */ + void powerOffVirtualGuest(long id); + + /** + * Power on a guest + * + * @param id + * id of the virtual guest + */ + void powerOnVirtualGuest(long id); + + /** + * pause the guest. + * + * @param id + * id of the virtual guest + */ + void pauseVirtualGuest(long id); + + /** + * resume the guest. + * + * @param id + * id of the virtual guest + */ + void resumeVirtualGuest(long id); } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerAsyncClientTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerAsyncClientTest.java index 1b9333aa2a..e8c4c34247 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerAsyncClientTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/SoftLayerAsyncClientTest.java @@ -44,10 +44,12 @@ public class SoftLayerAsyncClientTest extends BaseSoftLayerAsyncClientTest + * + * ==================================================================== + * Licensed 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.softlayer.features; + +import java.io.IOException; +import java.lang.reflect.Method; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import com.google.common.collect.Iterables; +import com.google.inject.TypeLiteral; + +/** + * Tests annotation parsing of {@code DatacenterAsyncClient} + * + * @author Adrian Cole + */ +@Test(groups = "unit") +public class DatacenterAsyncClientTest extends BaseSoftLayerAsyncClientTest { + + public void testListDatacenters() throws SecurityException, NoSuchMethodException, IOException { + Method method = DatacenterAsyncClient.class.getMethod("listDatacenters"); + HttpRequest httpRequest = processor.createRequest(method); + + assertRequestLineEquals(httpRequest, + "GET https://api.softlayer.com/rest/v3/SoftLayer_Location_Datacenter/Datacenters.json HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + // now make sure request filters apply by replaying + httpRequest = Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + httpRequest = Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, + "GET https://api.softlayer.com/rest/v3/SoftLayer_Location_Datacenter/Datacenters.json HTTP/1.1"); + // for example, using basic authentication, we should get "only one" + // header + assertNonPayloadHeadersEqual(httpRequest, + "Accept: application/json\nAuthorization: Basic YXBpS2V5OnNlY3JldEtleQ==\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseJson.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + + public void testGetDatacenter() throws SecurityException, NoSuchMethodException, IOException { + Method method = DatacenterAsyncClient.class.getMethod("getDatacenter", long.class); + HttpRequest httpRequest = processor.createRequest(method, 1234); + + assertRequestLineEquals(httpRequest, + "GET https://api.softlayer.com/rest/v3/SoftLayer_Location_Datacenter/1234.json?objectMask=locationAddress HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ParseJson.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } +} diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/DatacenterClientLiveTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/DatacenterClientLiveTest.java new file mode 100644 index 0000000000..4605e91381 --- /dev/null +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/DatacenterClientLiveTest.java @@ -0,0 +1,64 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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.softlayer.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.util.Set; + +import org.jclouds.softlayer.domain.Datacenter; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code DatacenterClient} + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class DatacenterClientLiveTest extends BaseSoftLayerClientLiveTest { + @BeforeGroups(groups = { "live" }) + public void setupClient() { + super.setupClient(); + client = context.getApi().getDatacenterClient(); + } + + private DatacenterClient client; + + @Test + public void testListDatacenters() throws Exception { + Set response = client.listDatacenters(); + assert null != response; + assertTrue(response.size() >= 0); + for (Datacenter vg : response) { + Datacenter newDetails = client.getDatacenter(vg.getId()); + assertEquals(vg.getId(), newDetails.getId()); + checkDatacenter(vg); + } + } + + private void checkDatacenter(Datacenter vg) { + assert vg.getId() > 0 : vg; + assert vg.getName() != null : vg; + assert vg.getLongName() != null : vg; + } + +} diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestAsyncClientTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestAsyncClientTest.java index 42bfb14232..c473564944 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestAsyncClientTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/VirtualGuestAsyncClientTest.java @@ -24,8 +24,10 @@ import java.lang.reflect.Method; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseJson; +import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; import org.testng.annotations.Test; @@ -44,8 +46,9 @@ public class VirtualGuestAsyncClientTest extends BaseSoftLayerAsyncClientTest> createTypeLiteral() {