diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java new file mode 100644 index 0000000000..4e3b01638d --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/domain/IpDetails.java @@ -0,0 +1,183 @@ +/** + * 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.glesys.domain; + +import com.google.gson.annotations.SerializedName; + +/** + * Represents detailed information about an available IP address. + * + * @author Mattias Holmqvist + */ +public class IpDetails { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + protected String datacenter; + protected String ipversion; + protected String ptr; + protected String platform; + protected String address; + protected String netmask; + protected String broadcast; + protected String gateway; + + public Builder datacenter(String datacenter) { + this.datacenter = datacenter; + return this; + } + + public Builder ipversion(String ipversion) { + this.ipversion = ipversion; + return this; + } + + public Builder ptr(String ptr) { + this.ptr = ptr; + return this; + } + + public Builder platform(String platform) { + this.platform = platform; + return this; + } + + public IpDetails build() { + return new IpDetails(datacenter, ipversion, ptr, platform, + address, netmask, broadcast, gateway); + } + + public Builder address(String address) { + this.address = address; + return this; + } + + public Builder netmask(String netmask) { + this.netmask = netmask; + return this; + } + + public Builder broadcast(String broadcast) { + this.broadcast = broadcast; + return this; + } + + public Builder gateway(String gateway) { + this.gateway = gateway; + return this; + } + } + + protected String datacenter; + protected String ipversion; + @SerializedName("PTR") + protected String ptr; + protected String platform; + protected String address; + protected String netmask; + protected String broadcast; + protected String gateway; + + public IpDetails(String datacenter, String ipversion, String ptr, String platform, + String address, String netmask, String broadcast, String gateway) { + this.datacenter = datacenter; + this.ipversion = ipversion; + this.ptr = ptr; + this.platform = platform; + this.address = address; + this.netmask = netmask; + this.broadcast = broadcast; + this.gateway = gateway; + } + + public String getDatacenter() { + return datacenter; + } + + public String getIpversion() { + return ipversion; + } + + public String getPtr() { + return ptr; + } + + public String getPlatform() { + return platform; + } + + public String getAddress() { + return address; + } + + public String getNetmask() { + return netmask; + } + + public String getBroadcast() { + return broadcast; + } + + public String getGateway() { + return gateway; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + IpDetails ipDetails = (IpDetails) o; + + if (address != null ? !address.equals(ipDetails.address) : ipDetails.address != null) return false; + if (broadcast != null ? !broadcast.equals(ipDetails.broadcast) : ipDetails.broadcast != null) return false; + if (datacenter != null ? !datacenter.equals(ipDetails.datacenter) : ipDetails.datacenter != null) return false; + if (gateway != null ? !gateway.equals(ipDetails.gateway) : ipDetails.gateway != null) return false; + if (ipversion != null ? !ipversion.equals(ipDetails.ipversion) : ipDetails.ipversion != null) return false; + if (netmask != null ? !netmask.equals(ipDetails.netmask) : ipDetails.netmask != null) return false; + if (platform != null ? !platform.equals(ipDetails.platform) : ipDetails.platform != null) return false; + if (ptr != null ? !ptr.equals(ipDetails.ptr) : ipDetails.ptr != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = datacenter != null ? datacenter.hashCode() : 0; + result = 31 * result + (ipversion != null ? ipversion.hashCode() : 0); + result = 31 * result + (ptr != null ? ptr.hashCode() : 0); + result = 31 * result + (platform != null ? platform.hashCode() : 0); + result = 31 * result + (address != null ? address.hashCode() : 0); + result = 31 * result + (netmask != null ? netmask.hashCode() : 0); + result = 31 * result + (broadcast != null ? broadcast.hashCode() : 0); + result = 31 * result + (gateway != null ? gateway.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return String.format("IpDetails[datacenter=%s, ipversion=%s, platform=%s, PTR=%s, " + + "address=%s, netmask=%s, broadcast=%s, gateway=%s", + datacenter, ipversion, platform, ptr, address, netmask, broadcast, gateway); + } +} diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java index 80a9986326..6f67d23f7f 100644 --- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpAsyncClient.java @@ -19,6 +19,7 @@ package org.jclouds.glesys.features; import com.google.common.util.concurrent.ListenableFuture; +import org.jclouds.glesys.domain.IpDetails; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.RequestFilters; @@ -56,4 +57,14 @@ public interface IpAsyncClient { @PathParam("datacenter") String datacenter, @PathParam("platform") String platform); + /** + * @see IpClient#getIpDetails + */ + @GET + @Path("/ip/details/ipaddress/{ipaddress}/format/json") + @Consumes(MediaType.APPLICATION_JSON) + @SelectJson("details") + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture getIpDetails(@PathParam("ipaddress") String ipAddress); + } diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java index f144ff3b1a..3dae24ad29 100644 --- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/features/IpClient.java @@ -19,6 +19,7 @@ package org.jclouds.glesys.features; import org.jclouds.concurrent.Timeout; +import org.jclouds.glesys.domain.IpDetails; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -45,4 +46,12 @@ public interface IpClient { */ Set listFree(String ipversion, String datacenter, String platform); + /** + * Get a set of all IP addresses that are available and not used on any account or server. + * + * @return a set of free IP addresses + */ + IpDetails getIpDetails(String ipAddress); + + } \ No newline at end of file diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientLiveTest.java index 5a598abedc..b71933dc32 100644 --- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientLiveTest.java +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/IpClientLiveTest.java @@ -18,22 +18,25 @@ */ package org.jclouds.glesys.features; +import org.jclouds.glesys.domain.IpDetails; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import java.util.Set; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; /** * Tests behavior of {@code IpClient} * - * @author Adrian Cole + * @author Adrian Cole, Mattias Holmqvist */ @Test(groups = "live", testName = "IpClientLiveTest") public class IpClientLiveTest extends BaseGleSYSClientLiveTest { - @BeforeGroups(groups = { "live" }) + @BeforeGroups(groups = {"live"}) public void setupClient() { super.setupClient(); client = context.getApi().getIpClient(); @@ -43,7 +46,38 @@ public class IpClientLiveTest extends BaseGleSYSClientLiveTest { @Test public void testListFree() throws Exception { - Set freeIps = client.listFree("4", "Falkenberg", "OpenVZ"); - assertTrue(freeIps.size() >= 0); + Set freeIps = client.listFree("4", "Falkenberg", "Xen"); + assertTrue(freeIps.size() >= 1); } + + @Test + public void testGetOpenVZDetails() throws Exception { + Set openVzIps = client.listFree("4", "Falkenberg", "OpenVZ"); + assertTrue(openVzIps.size() >= 1); + String openVzIp = openVzIps.iterator().next(); + IpDetails ipDetails = client.getIpDetails(openVzIp); + assertEquals(ipDetails.getDatacenter(), "Falkenberg"); + assertEquals(ipDetails.getPlatform(), "OpenVZ"); + assertEquals(ipDetails.getIpversion(), "4"); + + // TODO: Ask Glesys to include address in response for OpenVZ? + // assertEquals(ipDetails.getAddress(), openVzIp); + } + + @Test + public void testGetXenDetails() throws Exception { + Set xenVzIps = client.listFree("4", "Falkenberg", "Xen"); + assertTrue(xenVzIps.size() >= 1); + String xenIp = xenVzIps.iterator().next(); + IpDetails ipDetails = client.getIpDetails(xenIp); + assertEquals(ipDetails.getDatacenter(), "Falkenberg"); + assertEquals(ipDetails.getPlatform(), "Xen"); + assertEquals(ipDetails.getIpversion(), "4"); + assertEquals(ipDetails.getAddress(), xenIp); + assertNotNull(ipDetails.getPtr()); + assertNotNull(ipDetails.getBroadcast()); + assertNotNull(ipDetails.getGateway()); + assertNotNull(ipDetails.getNetmask()); + } + } diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseFullIpDetailsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseFullIpDetailsTest.java new file mode 100644 index 0000000000..aa97302a63 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseFullIpDetailsTest.java @@ -0,0 +1,53 @@ +/** + * 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.glesys.parse; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.jclouds.glesys.config.GleSYSParserModule; +import org.jclouds.glesys.domain.IpDetails; +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.annotations.SelectJson; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +public class ParseFullIpDetailsTest extends BaseItemParserTest { + + @Override + protected String resource() { + return "/ip_get_details_xen.json"; + } + + @Override + @SelectJson("details") + @Consumes(MediaType.APPLICATION_JSON) + public IpDetails expected() { + return IpDetails.builder().datacenter("Falkenberg").ipversion("4").platform("Xen") + .ptr("109-74-10-64-static.serverhotell.net.").address("109.74.10.64").netmask("255.255.254.0") + .broadcast("109.74.11.255").gateway("109.74.10.1").build(); + } + + protected Injector injector() { + return Guice.createInjector(new GleSYSParserModule(), new GsonModule()); + } + +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java new file mode 100644 index 0000000000..52c0c98cd2 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/parse/ParseSimpleIpDetailsTest.java @@ -0,0 +1,60 @@ +/* + * 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.glesys.parse; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.jclouds.glesys.config.GleSYSParserModule; +import org.jclouds.glesys.domain.IpDetails; +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +/** + * @author Mattias Holmqvist + */ +@Test(groups = "unit", testName = "ParseSimpleIpDetailsTest") +public class ParseSimpleIpDetailsTest extends BaseItemParserTest { + + @Override + protected String resource() { + return "/ip_get_details.json"; + } + + @Override + @SelectJson("details") + @Consumes(MediaType.APPLICATION_JSON) + public IpDetails expected() { + + return IpDetails.builder() + .datacenter("Falkenberg") + .ipversion("4") + .platform("OpenVZ") + .ptr("31-192-227-37-static.serverhotell.net.").build(); + } + + protected Injector injector() { + return Guice.createInjector(new GleSYSParserModule(), new GsonModule()); + } +} diff --git a/sandbox-providers/glesys/src/test/resources/ip_get_details.json b/sandbox-providers/glesys/src/test/resources/ip_get_details.json new file mode 100644 index 0000000000..ec6724e7b3 --- /dev/null +++ b/sandbox-providers/glesys/src/test/resources/ip_get_details.json @@ -0,0 +1 @@ +{"response":{"status":{"code":"200","text":"OK"},"details":{"datacenter":"Falkenberg","ipversion":4,"PTR":"31-192-227-37-static.serverhotell.net.","platform":"OpenVZ"},"debug":{"input":{"ipaddress":"31.192.227.37"}}}} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/test/resources/ip_get_details_xen.json b/sandbox-providers/glesys/src/test/resources/ip_get_details_xen.json new file mode 100644 index 0000000000..10f696dbef --- /dev/null +++ b/sandbox-providers/glesys/src/test/resources/ip_get_details_xen.json @@ -0,0 +1 @@ +{"response":{"status":{"code":"200","text":"OK"},"details":{"datacenter":"Falkenberg","ipversion":4,"PTR":"109-74-10-64-static.serverhotell.net.","address":"109.74.10.64","netmask":"255.255.254.0","broadcast":"109.74.11.255","gateway":"109.74.10.1","nameservers":"79.99.4.100 79.99.4.101","platform":"Xen"},"debug":{"input":{"ipaddress":"109.74.10.64"}}}} \ No newline at end of file