diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java
index f309456207..36b77121b0 100755
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersConnection.java
@@ -23,6 +23,7 @@
*/
package org.jclouds.rackspace.cloudservers;
+import java.net.InetAddress;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@@ -37,14 +38,19 @@ import javax.ws.rs.PathParam;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder;
import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder;
+import org.jclouds.rackspace.cloudservers.binders.ShareIpBinder;
+import org.jclouds.rackspace.cloudservers.domain.Addresses;
import org.jclouds.rackspace.cloudservers.domain.Flavor;
import org.jclouds.rackspace.cloudservers.domain.Image;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.SharedIpGroup;
+import org.jclouds.rackspace.cloudservers.functions.IpAddress;
+import org.jclouds.rackspace.cloudservers.functions.ParseAddressesFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseImageFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseImageListFromGsonResponse;
+import org.jclouds.rackspace.cloudservers.functions.ParseInetAddressListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseServerFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseServerListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseSharedIpGroupFromGsonResponse;
@@ -59,8 +65,9 @@ import org.jclouds.rackspace.cloudservers.options.ListOptions;
import org.jclouds.rackspace.filters.AuthenticateRequest;
import org.jclouds.rest.EntityParam;
import org.jclouds.rest.ExceptionParser;
-import org.jclouds.rest.PostBinder;
-import org.jclouds.rest.PostParam;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.rest.MapEntityParam;
+import org.jclouds.rest.ParamParser;
import org.jclouds.rest.Query;
import org.jclouds.rest.RequestFilters;
import org.jclouds.rest.ResponseParser;
@@ -163,11 +170,61 @@ public interface CloudServersConnection {
@ResponseParser(ParseServerFromGsonResponse.class)
@Query(key = "format", value = "json")
@Path("/servers")
- @PostBinder(CreateServerOptions.class)
+ @MapBinder(CreateServerOptions.class)
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401),
// badMediaType(415), badRequest (400), serverCapacityUnavailable (503), overLimit (413)
- Server createServer(@PostParam("name") String name, @PostParam("imageId") int imageId,
- @PostParam("flavorId") int flavorId, CreateServerOptions... options);
+ Server createServer(@MapEntityParam("name") String name, @MapEntityParam("imageId") int imageId,
+ @MapEntityParam("flavorId") int flavorId, CreateServerOptions... options);
+
+ /**
+ * /** This operation allows you share an IP address to the specified server
+ *
+ * This operation shares an IP from an existing server in the specified shared IP group to
+ * another specified server in the same group. The operation modifies cloud network restrictions
+ * to allow IP traffic for the given IP to/from the server specified.
+ *
+ *
+ * Status Transition: ACTIVE - SHARE_IP - ACTIVE (if configureServer is true) ACTIVE -
+ * SHARE_IP_NO_CONFIG - ACTIVE
+ *
+ * @param configureServer
+ *
+ * if set to true, the server is configured with the new address, though the address is
+ * not enabled. Note that configuring the server does require a reboot.
+ *
+ * If set to false, does not bind the IP to the server itself. A heartbeat facility
+ * (e.g. keepalived) can then be used within the servers to perform health checks and
+ * manage IP failover.
+ * @return false if the server is not found
+ */
+ @PUT
+ @ExceptionParser(ReturnFalseOn404.class)
+ @Path("/servers/{id}/ips/public/{address}")
+ @MapBinder(ShareIpBinder.class)
+ // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
+ // (400), badMediaType(415), buildInProgress (409), overLimit (413)
+ boolean shareIp(@PathParam("address") @ParamParser(IpAddress.class) InetAddress addressToShare,
+ @PathParam("id") int serverToAssignAddressTo,
+ @MapEntityParam("sharedIpGroupId") int sharedIpGroup,
+ @MapEntityParam("configureServer") boolean configureServer);
+
+ /**
+ * This operation removes a shared IP address from the specified server.
+ *
+ * Status Transition: ACTIVE - DELETE_IP - ACTIVE
+ *
+ * @param addressToShare
+ * @param serverToAssignAddressTo
+ * @return
+ */
+ @DELETE
+ @ExceptionParser(ReturnFalseOn404.class)
+ @Path("/servers/{id}/ips/public/{address}")
+ // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized(401), badRequest (400),
+ // badMediaType(415), overLimit (413)
+ boolean unshareIp(
+ @PathParam("address") @ParamParser(IpAddress.class) InetAddress addressToShare,
+ @PathParam("id") int serverToAssignAddressTo);
/**
* This operation allows you to change the administrative password.
@@ -303,10 +360,10 @@ public interface CloudServersConnection {
@ResponseParser(ParseSharedIpGroupFromGsonResponse.class)
@Query(key = "format", value = "json")
@Path("/shared_ip_groups")
- @PostBinder(CreateSharedIpGroupOptions.class)
+ @MapBinder(CreateSharedIpGroupOptions.class)
// TODO: cloudSharedIpGroupsFault (400, 500), serviceUnavailable (503), unauthorized (401),
// badRequest (400), badMediaType(415), overLimit (413)
- SharedIpGroup createSharedIpGroup(@PostParam("name") String name,
+ SharedIpGroup createSharedIpGroup(@MapEntityParam("name") String name,
CreateSharedIpGroupOptions... options);
/**
@@ -323,4 +380,38 @@ public interface CloudServersConnection {
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400)
boolean deleteSharedIpGroup(@PathParam("id") int id);
+
+ /**
+ * List all server addresses
+ */
+ @GET
+ @ResponseParser(ParseAddressesFromGsonResponse.class)
+ @Query(key = "format", value = "json")
+ @Path("/servers/{id}/ips")
+ // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
+ // (400), overLimit (413)
+ Addresses listAddresses(@PathParam("id") int serverId);
+
+ /**
+ * List all public server addresses
+ */
+ @GET
+ @ResponseParser(ParseInetAddressListFromGsonResponse.class)
+ @Query(key = "format", value = "json")
+ @Path("/servers/{id}/ips/public")
+ // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
+ // (400), overLimit (413)
+ List listPublicAddresses(@PathParam("id") int serverId);
+
+ /**
+ * List all private server addresses
+ */
+ @GET
+ @ResponseParser(ParseInetAddressListFromGsonResponse.class)
+ @Query(key = "format", value = "json")
+ @Path("/servers/{id}/ips/private")
+ // TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
+ // (400), overLimit (413)
+ List listPrivateAddresses(@PathParam("id") int serverId);
+
}
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java
index a6e5081d39..16d6e196a5 100644
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeAdminPassBinder.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.binders;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java
index 93bc8bf95b..3537e0fd19 100644
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ChangeServerNameBinder.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.binders;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java
new file mode 100644
index 0000000000..2427ed08f0
--- /dev/null
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/binders/ShareIpBinder.java
@@ -0,0 +1,67 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.binders;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.binders.JsonBinder;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ *
+ * @author Adrian Cole
+ *
+ */
+public class ShareIpBinder extends JsonBinder {
+
+ @SuppressWarnings("unused")
+ private class ShareIpRequest {
+ final int sharedIpGroupId;
+ Boolean configureServer;
+
+ private ShareIpRequest(int sharedIpGroupId) {
+ this.sharedIpGroupId = sharedIpGroupId;
+ }
+
+ }
+
+ @Override
+ public void addEntityToRequest(Map postParams, HttpRequest request) {
+ ShareIpRequest createRequest = new ShareIpRequest(Integer.parseInt(checkNotNull(postParams
+ .get("sharedIpGroupId"))));
+ if (Boolean.parseBoolean(checkNotNull(postParams.get("configureServer")))) {
+ createRequest.configureServer = new Boolean(true);
+ }
+ super.addEntityToRequest(ImmutableMap.of("shareIp", createRequest), request);
+ }
+
+ @Override
+ public void addEntityToRequest(Object toBind, HttpRequest request) {
+ throw new IllegalStateException("shareIp is needs parameters");
+ }
+}
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/IpAddress.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/IpAddress.java
new file mode 100644
index 0000000000..d35029c839
--- /dev/null
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/IpAddress.java
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.functions;
+
+import java.net.InetAddress;
+
+import com.google.common.base.Function;
+
+public class IpAddress implements Function {
+
+ public String apply(Object from) {
+ return ((InetAddress) from).getHostAddress();
+ }
+
+}
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponse.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponse.java
new file mode 100644
index 0000000000..931b691170
--- /dev/null
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponse.java
@@ -0,0 +1,60 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.functions;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.rackspace.cloudservers.domain.Addresses;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+
+/**
+ * This parses {@link Addresses} from a gson string.
+ *
+ * @author Adrian Cole
+ */
+public class ParseAddressesFromGsonResponse extends ParseJson {
+
+ @Inject
+ public ParseAddressesFromGsonResponse(Gson gson) {
+ super(gson);
+ }
+
+ private static class AddressesListResponse {
+ Addresses addresses;
+ }
+
+ public Addresses apply(InputStream stream) {
+
+ try {
+ return gson.fromJson(new InputStreamReader(stream, "UTF-8"), AddressesListResponse.class).addresses;
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("jclouds requires UTF-8 encoding", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponse.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponse.java
new file mode 100644
index 0000000000..d27e070912
--- /dev/null
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponse.java
@@ -0,0 +1,65 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.functions;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+
+import org.jclouds.http.functions.ParseJson;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+
+/**
+ * This parses a list of {@link InetAddress} from a gson string.
+ *
+ * @author Adrian Cole
+ */
+public class ParseInetAddressListFromGsonResponse extends ParseJson> {
+
+ @Inject
+ public ParseInetAddressListFromGsonResponse(Gson gson) {
+ super(gson);
+ }
+
+ Map> addressMap;
+
+ public List apply(InputStream stream) {
+ Type type = new TypeToken>>() {
+ }.getType();
+ try {
+ Map> map = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
+ type);
+ return map.values().iterator().next();
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("jclouds requires UTF-8 encoding", e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java
index ad20608626..38b6541b85 100644
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateServerOptions.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.options;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java
index fbef397861..70f6310a36 100644
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/CreateSharedIpGroupOptions.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.options;
import static com.google.common.base.Preconditions.checkArgument;
diff --git a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/ListOptions.java b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/ListOptions.java
index c9d02656bb..f18e054b8e 100644
--- a/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/ListOptions.java
+++ b/rackspace/cloudservers/core/src/main/java/org/jclouds/rackspace/cloudservers/options/ListOptions.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.options;
import org.jclouds.rackspace.options.BaseListOptions;
diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionLiveTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionLiveTest.java
index 80de103e5f..94a4201cce 100755
--- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionLiveTest.java
+++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionLiveTest.java
@@ -25,7 +25,6 @@ package org.jclouds.rackspace.cloudservers;
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions.Builder.withServer;
-import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.withDetails;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
import static org.testng.Assert.assertEquals;
@@ -35,6 +34,7 @@ import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
+import java.net.InetAddress;
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;
@@ -46,13 +46,14 @@ import org.jclouds.rackspace.cloudservers.domain.Image;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.ServerStatus;
import org.jclouds.rackspace.cloudservers.domain.SharedIpGroup;
+import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshConnection;
+import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshConnectionModule;
import org.jclouds.util.Utils;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
@@ -119,8 +120,7 @@ public class CloudServersConnectionLiveTest {
for (Image image : response) {
assertTrue(image.getId() >= 1);
assert null != image.getName() : image;
- // sometimes this is not present per: Web Hosting #118820
- // assert null != image.getCreated() : image;
+ assert null != image.getCreated() : image;
assert null != image.getUpdated() : image;
assert null != image.getStatus() : image;
}
@@ -266,16 +266,8 @@ public class CloudServersConnectionLiveTest {
}
assertNotNull(sharedIpGroup.getName());
sharedIpGroupId = sharedIpGroup.getId();
- assertEquals(sharedIpGroup.getServers(), ImmutableList.of(serverId));
- }
-
- @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreateSharedIpGroup" })
- void testDeleteSharedIpGroup() {
- if (sharedIpGroupId > 0) {
- connection.deleteSharedIpGroup(sharedIpGroupId);
- SharedIpGroup server = connection.getSharedIpGroup(sharedIpGroupId);
- assertEquals(server, SharedIpGroup.NOT_FOUND);
- }
+ // Response doesn't include the server id Web Hosting #119311
+ // assertEquals(sharedIpGroup.getServers(), ImmutableList.of(serverId));
}
private int sharedIpGroupId;
@@ -284,6 +276,9 @@ public class CloudServersConnectionLiveTest {
private int serverId;
private String adminPass;
Map metadata = ImmutableMap.of("jclouds", "rackspace");
+ private InetAddress ip;
+ private int serverId2;
+ private String adminPass2;
@Test(timeOut = 5 * 60 * 1000)
public void testCreateServer() throws Exception {
@@ -305,18 +300,16 @@ public class CloudServersConnectionLiveTest {
assertNotNull(server.getAdminPass());
serverId = server.getId();
adminPass = server.getAdminPass();
+ ip = server.getAddresses().getPublicAddresses().iterator().next();
assertEquals(server.getStatus(), ServerStatus.BUILD);
- blockUntilActive(server);
+ blockUntilActive(serverId);
}
- private void blockUntilActive(Server server) throws InterruptedException {
- ServerStatus currentStatus = server.getStatus();
- Server currentDetails = server;
- while (currentStatus != ServerStatus.ACTIVE) {
+ private void blockUntilActive(int serverId) throws InterruptedException {
+ for (Server currentDetails = connection.getServer(serverId); currentDetails.getStatus() != ServerStatus.ACTIVE; currentDetails = connection
+ .getServer(serverId)) {
+ System.out.printf("blocking on status active%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
- currentDetails = connection.getServer(serverId);
- System.out.println(currentDetails);
- currentStatus = currentDetails.getStatus();
}
}
@@ -330,8 +323,14 @@ public class CloudServersConnectionLiveTest {
assertEquals(new Integer(2), server.getImageId());
assertEquals(new Integer(1), server.getFlavorId());
assertNotNull(server.getAddresses());
+ // listAddresses tests..
+ assertEquals(connection.listAddresses(serverId), server.getAddresses());
assertEquals(server.getAddresses().getPublicAddresses().size(), 1);
+ assertEquals(connection.listPublicAddresses(serverId), server.getAddresses()
+ .getPublicAddresses());
assertEquals(server.getAddresses().getPrivateAddresses().size(), 1);
+ assertEquals(connection.listPrivateAddresses(serverId), server.getAddresses()
+ .getPrivateAddresses());
// check metadata
assertEquals(server.getMetadata(), metadata);
@@ -342,6 +341,14 @@ public class CloudServersConnectionLiveTest {
* this tests "personality" as the file looked up was sent during server creation
*/
private void checkPassOk(Server newDetails, String pass) throws IOException {
+ try {
+ doCheckPass(newDetails, pass);
+ } catch (SshException e) {// try twice in case there is a network timeout
+ doCheckPass(newDetails, pass);
+ }
+ }
+
+ private void doCheckPass(Server newDetails, String pass) throws IOException {
SshConnection connection = sshFactory.create(newDetails.getAddresses().getPublicAddresses()
.get(0), 22, "root", pass);
try {
@@ -355,35 +362,137 @@ public class CloudServersConnectionLiveTest {
}
}
+ private ExecResponse exec(Server details, String pass, String command) throws IOException {
+ SshConnection connection = sshFactory.create(details.getAddresses().getPublicAddresses().get(
+ 0), 22, "root", pass);
+ try {
+ connection.connect();
+ return connection.exec(command);
+ } finally {
+ if (connection != null)
+ connection.disconnect();
+ }
+ }
+
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testRenameServer() throws Exception {
Server server = connection.getServer(serverId);
String oldName = server.getName();
assertTrue(connection.renameServer(serverId, oldName + "new"));
- blockUntilActive(server);
+ blockUntilActive(serverId);
assertEquals(oldName + "new", connection.getServer(serverId).getName());
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
public void testChangePassword() throws Exception {
- Server server = connection.getServer(serverId);
assertTrue(connection.changeAdminPass(serverId, "elmo"));
- blockUntilActive(server);
+ blockUntilActive(serverId);
checkPassOk(connection.getServer(serverId), "elmo");
this.adminPass = "elmo";
}
- // TODO test createServer.withSharedIpGroup
- // TODO test createServer.withSharedIp
+ @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateSharedIpGroup")
+ public void testCreateServerIp() throws Exception {
+ int imageId = 2;
+ int flavorId = 1;
+ Server server = null;
+ while (server == null) {
+ String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
+ try {
+ server = connection.createServer(serverName, imageId, flavorId, withFile(
+ "/etc/jclouds.txt", "rackspace".getBytes()).withMetadata(metadata)
+ .withSharedIpGroup(sharedIpGroupId).withSharedIp(ip));
+ } catch (UndeclaredThrowableException e) {
+ HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
+ if (htpe.getResponse().getStatusCode() == 400)
+ continue;
+ throw e;
+ }
+ }
+ assertNotNull(server.getAdminPass());
+ serverId2 = server.getId();
+ adminPass2 = server.getAdminPass();
+ blockUntilActive(serverId2);
+ assertIpConfigured(server, adminPass2);
+ assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses()
+ + " doesn't contain " + ip;
+ assertEquals(server.getSharedIpGroupId(), new Integer(sharedIpGroupId));
+ }
- // must be last!
- @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testChangePassword", "testRenameServer" })
- void deleteServer() {
+ private void assertIpConfigured(Server server, String password) {
+ try {
+ ExecResponse response = exec(server, password, "ifconfig -a");
+ assert response.getOutput().indexOf(ip.getHostAddress()) > 0 : String.format(
+ "server %s didn't get ip %s%n%s", server, ip, response);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } catch (AssertionError e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServerIp")
+ public void testUnshare() throws Exception {
+ connection.unshareIp(ip, serverId2);
+ blockUntilActive(serverId2);
+ Server server = connection.getServer(serverId2);
+ assert !server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
+ assertIpNotConfigured(server, adminPass2);
+ }
+
+ private void assertIpNotConfigured(Server server, String password) {
+ try {
+ ExecResponse response = exec(server, password, "ifconfig -a");
+ assert response.getOutput().indexOf(ip.getHostAddress()) == -1 : String.format(
+ "server %s still has get ip %s%n%s", server, ip, response);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } catch (AssertionError e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testUnshare")
+ public void testShareConfig() throws Exception {
+ connection.shareIp(ip, serverId2, sharedIpGroupId, true);
+ blockUntilActive(serverId2);
+ Server server = connection.getServer(serverId2);
+ assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
+ assertIpConfigured(server, adminPass2);
+ testUnshare();
+ }
+
+ @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testShareConfig")
+ public void testShareNoConfig() throws Exception {
+ connection.shareIp(ip, serverId2, sharedIpGroupId, false);
+ blockUntilActive(serverId2);
+ Server server = connection.getServer(serverId2);
+ assert server.getAddresses().getPublicAddresses().contains(ip) : server.getAddresses();
+ assertIpNotConfigured(server, adminPass2);
+ testUnshare();
+ }
+
+ // must be last!. current order is only positionally guaranteed when in sequential mode.
+ @Test
+ void deleteServers() {
if (serverId > 0) {
connection.deleteServer(serverId);
Server server = connection.getServer(serverId);
assertEquals(server, Server.NOT_FOUND);
}
+ if (serverId2 > 0) {
+ connection.deleteServer(serverId2);
+ Server server = connection.getServer(serverId2);
+ assertEquals(server, Server.NOT_FOUND);
+ }
}
+ @Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "deleteServers" })
+ void testDeleteSharedIpGroup() {
+ if (sharedIpGroupId > 0) {
+ connection.deleteSharedIpGroup(sharedIpGroupId);
+ SharedIpGroup server = connection.getSharedIpGroup(sharedIpGroupId);
+ assertEquals(server, SharedIpGroup.NOT_FOUND);
+ }
+ }
}
diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java
index dc93a089b2..0011c18ae5 100755
--- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java
+++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/CloudServersConnectionTest.java
@@ -49,10 +49,12 @@ import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.rackspace.Authentication;
+import org.jclouds.rackspace.cloudservers.functions.ParseAddressesFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseImageFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseImageListFromGsonResponse;
+import org.jclouds.rackspace.cloudservers.functions.ParseInetAddressListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseServerFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseServerListFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseSharedIpGroupFromGsonResponse;
@@ -168,7 +170,7 @@ public class CloudServersConnectionTest {
assertEquals(processor.createResponseParser(method).getClass(),
ParseServerFromGsonResponse.class);
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
- assertNotNull(processor.getPostEntityBinderOrNull(method, new Object[] { "", 1, 2,
+ assertNotNull(processor.getMapEntityBinderOrNull(method, new Object[] { "", 1, 2,
new CreateServerOptions[] { CreateServerOptions.Builder.withSharedIpGroup(1) } }));
}
@@ -406,6 +408,65 @@ public class CloudServersConnectionTest {
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
+ public void testShareIpNoConfig() throws SecurityException, NoSuchMethodException,
+ UnknownHostException {
+ Method method = CloudServersConnection.class.getMethod("shareIp", InetAddress.class,
+ int.class, int.class, boolean.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {
+ InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), 2, 3, false });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips/public/127.0.0.1");
+ assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
+ assertEquals(httpMethod.getHeaders().size(), 2);
+ assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
+ .singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
+ assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
+ .singletonList(MediaType.APPLICATION_JSON));
+ assertEquals("{\"shareIp\":{\"sharedIpGroupId\":3}}", httpMethod.getEntity());
+ assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
+ ReturnFalseOn404.class);
+ assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
+ }
+
+ public void testShareIpConfig() throws SecurityException, NoSuchMethodException,
+ UnknownHostException {
+ Method method = CloudServersConnection.class.getMethod("shareIp", InetAddress.class,
+ int.class, int.class, boolean.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {
+ InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), 2, 3, true });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips/public/127.0.0.1");
+ assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
+ assertEquals(httpMethod.getHeaders().size(), 2);
+ assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
+ .singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
+ assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
+ .singletonList(MediaType.APPLICATION_JSON));
+ assertEquals("{\"shareIp\":{\"sharedIpGroupId\":3,\"configureServer\":true}}", httpMethod
+ .getEntity());
+ assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
+ ReturnFalseOn404.class);
+ assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
+ }
+
+ public void testUnshareIpNoConfig() throws SecurityException, NoSuchMethodException,
+ UnknownHostException {
+ Method method = CloudServersConnection.class.getMethod("unshareIp", InetAddress.class,
+ int.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {
+ InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }), 2, 3, false });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips/public/127.0.0.1");
+ assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
+ assertEquals(httpMethod.getHeaders().size(), 0);
+ assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
+ ReturnFalseOn404.class);
+ assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
+ }
+
public void testChangeAdminPass() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("changeAdminPass", int.class,
String.class);
@@ -562,7 +623,7 @@ public class CloudServersConnectionTest {
assertEquals(processor.createResponseParser(method).getClass(),
ParseSharedIpGroupFromGsonResponse.class);
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
- assertNotNull(processor.getPostEntityBinderOrNull(method, new Object[] { "",
+ assertNotNull(processor.getMapEntityBinderOrNull(method, new Object[] { "",
new CreateSharedIpGroupOptions[] { withServer(2) } }));
}
@@ -579,6 +640,45 @@ public class CloudServersConnectionTest {
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
+ public void testListAddresses() throws SecurityException, NoSuchMethodException {
+ Method method = CloudServersConnection.class.getMethod("listAddresses", int.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips");
+ assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
+ assertEquals(httpMethod.getMethod(), HttpMethod.GET);
+ assertEquals(httpMethod.getHeaders().size(), 0);
+ assertEquals(processor.createResponseParser(method).getClass(),
+ ParseAddressesFromGsonResponse.class);
+ }
+
+ public void testListPublicAddresses() throws SecurityException, NoSuchMethodException {
+ Method method = CloudServersConnection.class.getMethod("listPublicAddresses", int.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips/public");
+ assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
+ assertEquals(httpMethod.getMethod(), HttpMethod.GET);
+ assertEquals(httpMethod.getHeaders().size(), 0);
+ assertEquals(processor.createResponseParser(method).getClass(),
+ ParseInetAddressListFromGsonResponse.class);
+ }
+
+ public void testListPrivateAddresses() throws SecurityException, NoSuchMethodException {
+ Method method = CloudServersConnection.class.getMethod("listPrivateAddresses", int.class);
+ URI endpoint = URI.create("http://localhost");
+ HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
+ assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
+ assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/ips/private");
+ assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
+ assertEquals(httpMethod.getMethod(), HttpMethod.GET);
+ assertEquals(httpMethod.getHeaders().size(), 0);
+ assertEquals(processor.createResponseParser(method).getClass(),
+ ParseInetAddressListFromGsonResponse.class);
+ }
+
JaxrsAnnotationProcessor processor;
@BeforeClass
diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponseTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponseTest.java
new file mode 100644
index 0000000000..3341c73dd0
--- /dev/null
+++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseAddressesFromGsonResponseTest.java
@@ -0,0 +1,71 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.functions;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+import org.jclouds.http.functions.config.ParserModule;
+import org.jclouds.rackspace.cloudservers.domain.Addresses;
+import org.jclouds.util.DateService;
+import org.testng.annotations.Test;
+
+import com.google.gson.Gson;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.internal.ImmutableList;
+
+/**
+ * Tests behavior of {@code ParseAddressesFromGsonResponse}
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "cloudservers.ParseAddressesFromGsonResponseTest")
+public class ParseAddressesFromGsonResponseTest {
+
+ Injector i = Guice.createInjector(new ParserModule());
+ DateService dateService = new DateService();
+
+ public void testApplyInputStreamDetails() throws UnknownHostException {
+ InputStream is = getClass().getResourceAsStream("/test_list_addresses.json");
+
+ ParseAddressesFromGsonResponse parser = new ParseAddressesFromGsonResponse(i
+ .getInstance(Gson.class));
+ Addresses response = parser.apply(is);
+ List publicAddresses = ImmutableList.of(InetAddress.getByAddress(new byte[] {
+ 67, 23, 10, (byte) 132 }), InetAddress.getByAddress(new byte[] { 67, 23, 10,
+ (byte) 131 }));
+
+ List privateAddresses = ImmutableList.of(InetAddress.getByAddress(new byte[] {
+ 10, (byte) 176, 42, 16 }));
+
+ assertEquals(response.getPublicAddresses(), publicAddresses);
+ assertEquals(response.getPrivateAddresses(), privateAddresses);
+ }
+
+}
diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponseTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponseTest.java
new file mode 100644
index 0000000000..4dc8efd600
--- /dev/null
+++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/functions/ParseInetAddressListFromGsonResponseTest.java
@@ -0,0 +1,72 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.functions;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+import org.jclouds.http.functions.config.ParserModule;
+import org.jclouds.util.DateService;
+import org.testng.annotations.Test;
+
+import com.google.gson.Gson;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.internal.ImmutableList;
+
+/**
+ * Tests behavior of {@code ParseInetAddressListFromGsonResponse}
+ *
+ * @author Adrian Cole
+ */
+@Test(groups = "unit", testName = "cloudservers.ParseInetAddressListFromGsonResponseTest")
+public class ParseInetAddressListFromGsonResponseTest {
+
+ Injector i = Guice.createInjector(new ParserModule());
+ DateService dateService = new DateService();
+
+ public void testPublic() throws UnknownHostException {
+ InputStream is = getClass().getResourceAsStream("/test_list_addresses_public.json");
+
+ ParseInetAddressListFromGsonResponse parser = new ParseInetAddressListFromGsonResponse(i
+ .getInstance(Gson.class));
+ List response = parser.apply(is);
+ assertEquals(response, ImmutableList.of(InetAddress.getByAddress(new byte[] { 67, 23, 10,
+ (byte) 132 }), InetAddress.getByAddress(new byte[] { 67, 23, 10, (byte) 131 })));
+ }
+
+ public void testPrivate() throws UnknownHostException {
+ InputStream is = getClass().getResourceAsStream("/test_list_addresses_private.json");
+
+ ParseInetAddressListFromGsonResponse parser = new ParseInetAddressListFromGsonResponse(i
+ .getInstance(Gson.class));
+ List response = parser.apply(is);
+ assertEquals(response, ImmutableList.of(InetAddress.getByAddress(new byte[] { 10, (byte) 176,
+ 42, 16 })));
+ }
+}
diff --git a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/ListOptionsTest.java b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/ListOptionsTest.java
index dcf2428e34..f8944237dc 100644
--- a/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/ListOptionsTest.java
+++ b/rackspace/cloudservers/core/src/test/java/org/jclouds/rackspace/cloudservers/options/ListOptionsTest.java
@@ -1,3 +1,26 @@
+/**
+ *
+ * Copyright (C) 2009 Global Cloud Specialists, Inc.
+ *
+ * ====================================================================
+ * 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.rackspace.cloudservers.options;
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.*;
diff --git a/rackspace/cloudservers/core/src/test/resources/test_list_addresses.json b/rackspace/cloudservers/core/src/test/resources/test_list_addresses.json
new file mode 100644
index 0000000000..24441b8fac
--- /dev/null
+++ b/rackspace/cloudservers/core/src/test/resources/test_list_addresses.json
@@ -0,0 +1,12 @@
+{
+ "addresses" : {
+ "public" : [
+ "67.23.10.132",
+ "67.23.10.131"
+ ],
+ "private" : [
+ "10.176.42.16"
+ ]
+ }
+}
+
diff --git a/rackspace/cloudservers/core/src/test/resources/test_list_addresses_private.json b/rackspace/cloudservers/core/src/test/resources/test_list_addresses_private.json
new file mode 100644
index 0000000000..8c14cf3b93
--- /dev/null
+++ b/rackspace/cloudservers/core/src/test/resources/test_list_addresses_private.json
@@ -0,0 +1,8 @@
+{
+
+ "private" : [
+ "10.176.42.16"
+ ]
+
+}
+
diff --git a/rackspace/cloudservers/core/src/test/resources/test_list_addresses_public.json b/rackspace/cloudservers/core/src/test/resources/test_list_addresses_public.json
new file mode 100644
index 0000000000..22982ccb40
--- /dev/null
+++ b/rackspace/cloudservers/core/src/test/resources/test_list_addresses_public.json
@@ -0,0 +1,7 @@
+{
+ "public" : [
+ "67.23.10.132",
+ "67.23.10.131"
+ ]
+}
+