Issue 230: completed coding ibmdev support

This commit is contained in:
Adrian Cole 2010-06-08 00:31:51 -07:00
parent f4e030d10f
commit b87fcd4ee2
44 changed files with 939 additions and 564 deletions

View File

@ -112,7 +112,7 @@ public class ${providerName}ComputeServiceContextModule extends ${providerName}C
@Named("NAMING_CONVENTION")
@Singleton
String provideNamingConvention() {
return "%s-%d";
return "%s-%s";
}
@Singleton

View File

@ -20,7 +20,7 @@
"A clojure binding to the jclouds ComputeService.
Current supported services are:
[ec2, rimuhosting, terremark, vcloud, hostingdotcom]
[ec2, rimuhosting, terremark, vcloud, bluelock, ibmdev, hostingdotcom]
Here's an example of getting some compute configuration from rackspace:

View File

@ -206,6 +206,11 @@ public class TemplateOptions {
return this;
}
public TemplateOptions dontAuthorizePublicKey() {
this.publicKey = null;
return this;
}
/**
* authorized an rsa ssh key.
*/

View File

@ -28,6 +28,7 @@ import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@ -36,8 +37,6 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.ibmdev.binders.BindExpirationTimeToJsonPayload;
import org.jclouds.ibmdev.binders.SaveInstanceBinder;
import org.jclouds.ibmdev.domain.Address;
import org.jclouds.ibmdev.domain.Image;
import org.jclouds.ibmdev.domain.Instance;
@ -53,21 +52,20 @@ import org.jclouds.ibmdev.functions.ParseInstanceFromJson;
import org.jclouds.ibmdev.functions.ParseInstancesFromJson;
import org.jclouds.ibmdev.functions.ParseKeyFromJson;
import org.jclouds.ibmdev.functions.ParseKeysFromJson;
import org.jclouds.ibmdev.functions.ParseLongFromDate;
import org.jclouds.ibmdev.functions.ParseVolumeFromJson;
import org.jclouds.ibmdev.functions.ParseVolumesFromJson;
import org.jclouds.ibmdev.options.CreateInstanceOptions;
import org.jclouds.ibmdev.options.RestartInstanceOptions;
import org.jclouds.ibmdev.xml.LocationHandler;
import org.jclouds.ibmdev.xml.LocationsHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapPayloadParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
@ -101,7 +99,7 @@ public interface IBMDeveloperCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/images/{imageId}")
@ResponseParser(ParseImageFromJson.class)
ListenableFuture<Image> getImage(@PathParam("imageId") long id);
ListenableFuture<Image> getImage(@PathParam("imageId") String id);
/**
* @see IBMDeveloperCloudClient#deleteImage
@ -109,7 +107,7 @@ public interface IBMDeveloperCloudAsyncClient {
@DELETE
@Path("/images/{imageId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteImage(@PathParam("imageId") long id);
ListenableFuture<Void> deleteImage(@PathParam("imageId") String id);
/**
* @see IBMDeveloperCloudClient#setImageVisibility(long, Image.Visibility)
@ -118,9 +116,8 @@ public interface IBMDeveloperCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/images/{imageId}")
@ResponseParser(ParseImageFromJson.class)
@MapBinder(BindToJsonPayload.class)
ListenableFuture<Image> setImageVisibility(@PathParam("imageId") long id,
@MapPayloadParam("visibility") Image.Visibility visibility);
ListenableFuture<Image> setImageVisibility(@PathParam("imageId") String id,
@FormParam("visibility") Image.Visibility visibility);
/**
* @see IBMDeveloperCloudClient#listInstancesFromRequest(long)
@ -130,7 +127,7 @@ public interface IBMDeveloperCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(ParseInstancesFromJson.class)
ListenableFuture<Set<? extends Instance>> listInstancesFromRequest(
@PathParam("requestId") long requestId);
@PathParam("requestId") String requestId);
/**
* @see IBMDeveloperCloudClient#listInstances()
@ -147,24 +144,25 @@ public interface IBMDeveloperCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/instances/{instanceId}")
@ResponseParser(ParseInstanceFromJson.class)
ListenableFuture<Instance> getInstance(@PathParam("instanceId") long id);
ListenableFuture<Instance> getInstance(@PathParam("instanceId") String id);
/**
*
* @see IBMDeveloperCloudClient#extendReservationForInstance(long,Date)
*/
@PUT
@Path("/instances/{instanceId}")
@ResponseParser(ParseExpirationTimeFromJson.class)
ListenableFuture<Date> extendReservationForInstance(@PathParam("instanceId") long id,
@BinderParam(BindExpirationTimeToJsonPayload.class) Date expirationTime);
ListenableFuture<Date> extendReservationForInstance(@PathParam("instanceId") String id,
@FormParam("expirationTime") @ParamParser(ParseLongFromDate.class) Date expirationTime);
/**
* @see IBMDeveloperCloudClient#restartInstance
*/
@PUT
@Path("/instances/{instanceId}")
@MapBinder(RestartInstanceOptions.class)
ListenableFuture<Void> restartInstance(@PathParam("instanceId") long id,
@FormParams(keys = "state", values = "restart")
ListenableFuture<Void> restartInstance(@PathParam("instanceId") String id,
RestartInstanceOptions... options);
/**
@ -172,23 +170,21 @@ public interface IBMDeveloperCloudAsyncClient {
*/
@PUT
@Path("/instances/{instanceId}")
@MapBinder(SaveInstanceBinder.class)
@FormParams(keys = "state", values = "save")
@ResponseParser(ParseImageFromJson.class)
ListenableFuture<Image> saveInstanceToImage(@PathParam("instanceId") long id,
@MapPayloadParam("name") String toImageName,
@MapPayloadParam("description") String toImageDescription);
ListenableFuture<Image> saveInstanceToImage(@PathParam("instanceId") String id,
@FormParam("name") String toImageName,
@FormParam("description") String toImageDescription);
/**
* @see IBMDeveloperCloudClient#createInstanceInLocation
*/
@POST
@Path("/instances")
@MapBinder(CreateInstanceOptions.class)
@ResponseParser(ParseInstanceFromJson.class)
ListenableFuture<Instance> createInstanceInLocation(
@MapPayloadParam("location") String location, @MapPayloadParam("name") String name,
@MapPayloadParam("imageID") String imageID,
@MapPayloadParam("instanceType") String instanceType, CreateInstanceOptions... options);
ListenableFuture<Instance> createInstanceInLocation(@FormParam("location") String location,
@FormParam("name") String name, @FormParam("imageID") String imageID,
@FormParam("instanceType") String instanceType, CreateInstanceOptions... options);
/**
* @see IBMDeveloperCloudClient#deleteInstance
@ -196,7 +192,7 @@ public interface IBMDeveloperCloudAsyncClient {
@DELETE
@Path("/instances/{instanceId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteInstance(@PathParam("instanceId") long id);
ListenableFuture<Void> deleteInstance(@PathParam("instanceId") String id);
/**
* @see IBMDeveloperCloudClient#listKeys()
@ -211,36 +207,32 @@ public interface IBMDeveloperCloudAsyncClient {
*/
@POST
@Path("/keys")
@MapBinder(BindToJsonPayload.class)
@ResponseParser(ParseKeyFromJson.class)
ListenableFuture<Key> generateKeyPair(@MapPayloadParam("name") String name);
ListenableFuture<Key> generateKeyPair(@FormParam("name") String name);
/**
* @see IBMDeveloperCloudClient#addPublicKey(String, String)
*/
@POST
@Path("/keys")
@MapBinder(BindToJsonPayload.class)
ListenableFuture<Void> addPublicKey(@MapPayloadParam("name") String name,
@MapPayloadParam("publicKey") String publicKey);
ListenableFuture<Void> addPublicKey(@FormParam("name") String name,
@FormParam("publicKey") String publicKey);
/**
* @see IBMDeveloperCloudClient#updatePublicKey(String, String)
*/
@PUT
@Path("/keys/{keyName}")
@MapBinder(BindToJsonPayload.class)
ListenableFuture<Void> updatePublicKey(@PathParam("keyName") String name,
@MapPayloadParam("publicKey") String publicKey);
@FormParam("publicKey") String publicKey);
/**
* @see IBMDeveloperCloudClient#setDefaultStatusOfKey(String, boolean)
*/
@PUT
@Path("/keys/{keyName}")
@MapBinder(BindToJsonPayload.class)
ListenableFuture<Void> setDefaultStatusOfKey(@PathParam("keyName") String name,
@MapPayloadParam("default") boolean isDefault);
@FormParam("default") boolean isDefault);
/**
* @see IBMDeveloperCloudClient#getKey(String)
@ -272,11 +264,10 @@ public interface IBMDeveloperCloudAsyncClient {
*/
@POST
@Path("/storage")
@MapBinder(BindToJsonPayload.class)
@ResponseParser(ParseVolumeFromJson.class)
ListenableFuture<Volume> createVolumeInLocation(@MapPayloadParam("location") String location,
@MapPayloadParam("name") String name, @MapPayloadParam("format") String format,
@MapPayloadParam("size") String size);
ListenableFuture<Volume> createVolumeInLocation(@FormParam("location") String location,
@FormParam("name") String name, @FormParam("format") String format,
@FormParam("size") String size);
/**
* @see IBMDeveloperCloudClient#getVolume(long)
@ -285,7 +276,7 @@ public interface IBMDeveloperCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("/storage/{volumeId}")
@ResponseParser(ParseVolumeFromJson.class)
ListenableFuture<Volume> getVolume(@PathParam("volumeId") long id);
ListenableFuture<Volume> getVolume(@PathParam("volumeId") String id);
/**
* @see IBMDeveloperCloudClient#deleteVolume
@ -293,7 +284,7 @@ public interface IBMDeveloperCloudAsyncClient {
@DELETE
@Path("/storage/{volumeId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteVolume(@PathParam("volumeId") long id);
ListenableFuture<Void> deleteVolume(@PathParam("volumeId") String id);
/**
* @see IBMDeveloperCloudClient#listLocations()
@ -312,7 +303,7 @@ public interface IBMDeveloperCloudAsyncClient {
@Path("/locations/{locationId}")
@Consumes(MediaType.TEXT_XML)
@XMLResponseParser(LocationHandler.class)
ListenableFuture<Location> getLocation(@PathParam("locationId") long id);
ListenableFuture<Location> getLocation(@PathParam("locationId") String id);
/**
* @see IBMDeveloperCloudClient#listAddresses()
@ -327,9 +318,8 @@ public interface IBMDeveloperCloudAsyncClient {
*/
@POST
@Path("/addresses")
@MapBinder(BindToJsonPayload.class)
@ResponseParser(ParseAddressFromJson.class)
ListenableFuture<Address> allocateAddressInLocation(@MapPayloadParam("location") long locationId);
ListenableFuture<Address> allocateAddressInLocation(@FormParam("location") String locationId);
/**
* @see IBMDeveloperCloudClient#releaseAddress(long)
@ -337,5 +327,5 @@ public interface IBMDeveloperCloudAsyncClient {
@DELETE
@Path("/addresses/{addressId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> releaseAddress(@PathParam("addressId") long id);
ListenableFuture<Void> releaseAddress(@PathParam("addressId") String id);
}

View File

@ -65,7 +65,7 @@ import org.jclouds.rest.ResourceNotFoundException;
* @see <a href="http://www-180.ibm.com/cloud/enterprise/beta/support" />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface IBMDeveloperCloudClient {
/**
*
@ -80,7 +80,7 @@ public interface IBMDeveloperCloudClient {
* @throws AuthorizationException
* code 401 if the user is not authorized to view this image to section
*/
Image getImage(long id);
Image getImage(String id);
/**
* Deletes Image identified by the supplied Image ID.
@ -90,7 +90,7 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 412 if the image is in an invalid state to perform this operation
*/
void deleteImage(long id);
void deleteImage(String id);
/**
* If set to {@code Image.Visibility#PUBLIC}, makes the Image identified by the supplied Image ID
@ -103,7 +103,7 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 412 if the image is in an invalid state to perform this operation
*/
Image setImageVisibility(long id, Image.Visibility visibility);
Image setImageVisibility(String id, Image.Visibility visibility);
/**
*
@ -121,7 +121,7 @@ public interface IBMDeveloperCloudClient {
* @throws AuthorizationException
* code 401 if the currently authenticated user is not authorized to view this request
*/
Set<? extends Instance> listInstancesFromRequest(long requestId);
Set<? extends Instance> listInstancesFromRequest(String requestId);
/**
* Returns the Instance that the authenticated user manages with the specified {@code id}
@ -131,7 +131,7 @@ public interface IBMDeveloperCloudClient {
* code 401 if the currently authenticated user is not authorized to view this
* instance
*/
Instance getInstance(long id);
Instance getInstance(String id);
/**
* Requests a new Instance to be created.
@ -175,7 +175,7 @@ public interface IBMDeveloperCloudClient {
* <p/>
* code 412 The instance is in an invalid state to perform this operation
*/
Date extendReservationForInstance(long id, Date expirationTime);
Date extendReservationForInstance(String id, Date expirationTime);
/**
* Restart the instance
@ -198,7 +198,7 @@ public interface IBMDeveloperCloudClient {
* <p/>
* code 412 The instance is in an invalid state to perform this operation
*/
void restartInstance(long id, RestartInstanceOptions... options);
void restartInstance(String id, RestartInstanceOptions... options);
/**
* Saves an instance to a private image
@ -224,7 +224,7 @@ public interface IBMDeveloperCloudClient {
* <p/>
* code 412 The instance is in an invalid state to perform this operation
*/
Image saveInstanceToImage(long id, String toImageName, String toImageDescription);
Image saveInstanceToImage(String id, String toImageName, String toImageDescription);
/**
* Deletes the Instance that the authenticated user manages with the specified {@code id}
@ -234,7 +234,7 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 412 if the instance is in an invalid state to perform this operation
*/
void deleteInstance(long id);
void deleteInstance(String id);
/**
*
@ -354,7 +354,7 @@ public interface IBMDeveloperCloudClient {
* code 401 if the currently authenticated user is not authorized to view this storage
* volume
*/
Volume getVolume(long id);
Volume getVolume(String id);
/**
* Remove the specified storage volume for the authenticated user.
@ -365,7 +365,7 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 412 if the storage volume is not in the correct state to be deleted
*/
void deleteVolume(long id);
void deleteVolume(String id);
/**
*
@ -382,7 +382,7 @@ public interface IBMDeveloperCloudClient {
* @throws AuthorizationException
* code 401 if the user is not authorized
*/
Location getLocation(long id);
Location getLocation(String id);
/**
*
@ -394,6 +394,7 @@ public interface IBMDeveloperCloudClient {
Set<? extends Address> listAddresses();
/**
*
* Allocates a new static IP addresses for the authenticated user.
*
* @param locationId
@ -406,7 +407,7 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 409 ifhere are not enough resources in the cloud to fulfill this request
*/
Address allocateAddressInLocation(long locationId);
Address allocateAddressInLocation(String locationId);
/**
* Used to release the specified static IP addresses for the authenticated user.
@ -416,5 +417,5 @@ public interface IBMDeveloperCloudClient {
* @throws IllegalStateException
* code 412 address is in an invalid state to perform this operation
*/
void releaseAddress(long id);
void releaseAddress(String id);
}

View File

@ -25,6 +25,7 @@ package org.jclouds.ibmdev;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT;
import static org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_LOCATION;
import static org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_PASSWORD;
import static org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_USER;
@ -42,7 +43,9 @@ public class IBMDeveloperCloudPropertiesBuilder extends PropertiesBuilder {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT, "https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403");
properties.setProperty(PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT,
"https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403");
properties.setProperty(PROPERTY_IBMDEVELOPERCLOUD_LOCATION, "1");
return properties;
}
@ -62,8 +65,8 @@ public class IBMDeveloperCloudPropertiesBuilder extends PropertiesBuilder {
}
public IBMDeveloperCloudPropertiesBuilder withEndpoint(URI endpoint) {
properties.setProperty(PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT, checkNotNull(endpoint, "endpoint")
.toString());
properties.setProperty(PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT,
checkNotNull(endpoint, "endpoint").toString());
return this;
}
}

View File

@ -1,48 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.ibmdev.binders;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Date;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*
*/
public class BindExpirationTimeToJsonPayload extends BindToJsonPayload {
@Override
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
throw new IllegalStateException("Change Admin Pass is a PUT operation");
}
@Override
public void bindToRequest(HttpRequest request, Object toBind) {
checkArgument(toBind instanceof Date, "this binder is only valid for Date!");
super.bindToRequest(request, ImmutableMap.of("expirationTime", toBind));
}
}

View File

@ -1,40 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.ibmdev.binders;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
*
*
* @author Adrian Cole
*
*/
public class SaveInstanceBinder extends BindToJsonPayload {
@Override
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
postParams.put("state", "save");
bindToRequest(request,(Object) postParams);
}
}

View File

@ -18,9 +18,15 @@
*/
package org.jclouds.ibmdev.compute.config;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OsFamily.RHEL;
import static org.jclouds.ibmdev.options.CreateInstanceOptions.Builder.authorizePublicKey;
import static org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants.PROPERTY_IBMDEVELOPERCLOUD_LOCATION;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
@ -28,15 +34,22 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.LoadBalancerService;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -45,20 +58,30 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
import org.jclouds.ibmdev.compute.functions.InstanceToNodeMetadata;
import org.jclouds.ibmdev.config.IBMDeveloperCloudContextModule;
import org.jclouds.ibmdev.domain.Instance;
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
import org.jclouds.logging.Logger;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
@ -79,6 +102,8 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
}).to(InstanceToNodeMetadata.class);
bind(new TypeLiteral<ComputeServiceContext>() {
})
.to(
@ -104,104 +129,187 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
@Provides
@Named("DEFAULT")
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
return template.osFamily(UBUNTU);
return template.osFamily(RHEL);
}
@Provides
@Named("NAMING_CONVENTION")
@Singleton
String provideNamingConvention() {
return "%s-%d";
return "%s-%s";
}
@Provides
@Singleton
@Named("CREDENTIALS")
Map<String, String> credentialsMap() {
return new ConcurrentHashMap<String, String>();
}
@Singleton
public static class CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet extends
EncodeTagIntoNameRunNodesAndAddToSetStrategy {
private final IBMDeveloperCloudClient client;
private final Map<String, String> credentialsMap;
@Inject
protected CreateKeyPairEncodeTagIntoNameRunNodesAndAddToSet(
AddNodeWithTagStrategy addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy,
@Named("NAMING_CONVENTION") String nodeNamingConvention, ComputeUtils utils,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
IBMDeveloperCloudClient client,
@Named("CREDENTIALS") Map<String, String> credentialsMap) {
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, utils, executor);
this.client = checkNotNull(client, "client");
this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
}
@Override
public Map<?, ListenableFuture<Void>> execute(String tag, int count, Template template,
Set<NodeMetadata> nodes, Map<NodeMetadata, Exception> badNodes) {
String key = template.getOptions().getPublicKey();
if (key != null) {
template.getOptions().dontAuthorizePublicKey();
try {
client.addPublicKey(tag, key);
} catch (IllegalStateException e) {
// must not have been found
client.updatePublicKey(tag, key);
}
} else {
credentialsMap.put(tag, client.generateKeyPair(tag).getKeyMaterial());
}
return super.execute(tag, count, template, nodes, badNodes);
}
}
@Singleton
public static class IBMDeveloperCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
private final IBMDeveloperCloudClient client;
private final Predicate<Instance> instanceActive;
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
@Inject
protected IBMDeveloperCloudAddNodeWithTagStrategy() {
protected IBMDeveloperCloudAddNodeWithTagStrategy(IBMDeveloperCloudClient client,
@Named("ACTIVE") Predicate<Instance> instanceActive,
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
this.client = checkNotNull(client, "client");
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
this.instanceToNodeMetadata = checkNotNull(instanceToNodeMetadata,
"instanceToNodeMetadata");
}
@Override
public NodeMetadata execute(String tag, String name, Template template) {
/*
* TODO: implement
*/
return null;
Instance instance = client.createInstanceInLocation(template.getLocation().getId(), name,
template.getImage().getProviderId(), template.getSize().getProviderId(),
authorizePublicKey(tag));
instanceActive.apply(instance);
return instanceToNodeMetadata.apply(client.getInstance(instance.getId()));
}
}
@Singleton
public static class IBMDeveloperCloudRebootNodeStrategy implements RebootNodeStrategy {
private final IBMDeveloperCloudClient client;
private final Predicate<Instance> instanceActive;
@Inject
protected IBMDeveloperCloudRebootNodeStrategy() {
protected IBMDeveloperCloudRebootNodeStrategy(IBMDeveloperCloudClient client,
@Named("ACTIVE") Predicate<Instance> instanceActive) {
this.client = checkNotNull(client, "client");
this.instanceActive = checkNotNull(instanceActive, "instanceActive");
}
@Override
public boolean execute(String id) {
/*
* TODO: implement
*/
return false;
client.restartInstance(id);
return instanceActive.apply(client.getInstance(id));
}
}
@Singleton
@Provides
Map<Instance.Status, NodeState> provideServerToNodeState() {
return ImmutableMap.<Instance.Status, NodeState> builder().put(Instance.Status.ACTIVE,
NodeState.RUNNING)//
.put(Instance.Status.STOPPED, NodeState.SUSPENDED)//
.put(Instance.Status.REMOVED, NodeState.TERMINATED)//
.put(Instance.Status.DEPROVISIONING, NodeState.PENDING)//
.put(Instance.Status.FAILED, NodeState.ERROR)//
.put(Instance.Status.NEW, NodeState.PENDING)//
.put(Instance.Status.PROVISIONING, NodeState.PENDING)//
.put(Instance.Status.REJECTED, NodeState.ERROR)//
.put(Instance.Status.RESTARTING, NodeState.PENDING)//
.put(Instance.Status.STARTING, NodeState.PENDING)//
.put(Instance.Status.STOPPING, NodeState.PENDING)//
.put(Instance.Status.UNKNOWN, NodeState.UNKNOWN).build();
}
@Singleton
public static class IBMDeveloperCloudListNodesStrategy implements ListNodesStrategy {
private final IBMDeveloperCloudClient client;
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
@Inject
protected IBMDeveloperCloudListNodesStrategy() {
protected IBMDeveloperCloudListNodesStrategy(IBMDeveloperCloudClient client,
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
this.client = client;
this.instanceToNodeMetadata = instanceToNodeMetadata;
}
@Override
public Iterable<? extends ComputeMetadata> list() {
/*
* TODO: implement
*/return null;
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
/*
* TODO: implement
*/
return null;
return Iterables.filter(Iterables
.transform(client.listInstances(), instanceToNodeMetadata), filter);
}
}
@Singleton
public static class IBMDeveloperCloudGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final IBMDeveloperCloudClient client;
private final Function<Instance, NodeMetadata> instanceToNodeMetadata;
@Inject
protected IBMDeveloperCloudGetNodeMetadataStrategy() {
protected IBMDeveloperCloudGetNodeMetadataStrategy(IBMDeveloperCloudClient client,
Function<Instance, NodeMetadata> instanceToNodeMetadata) {
this.client = client;
this.instanceToNodeMetadata = instanceToNodeMetadata;
}
@Override
public NodeMetadata execute(String id) {
/*
* TODO: implement
*/
return null;
Instance instance = client.getInstance(checkNotNull(id, "id"));
return instance == null ? null : instanceToNodeMetadata.apply(instance);
}
}
@Singleton
public static class IBMDeveloperCloudDestroyNodeStrategy implements DestroyNodeStrategy {
private final IBMDeveloperCloudClient client;
private final Predicate<Instance> instanceRemoved;
@Inject
protected IBMDeveloperCloudDestroyNodeStrategy() {
protected IBMDeveloperCloudDestroyNodeStrategy(IBMDeveloperCloudClient client,
@Named("REMOVED") Predicate<Instance> instanceRemoved) {
this.client = checkNotNull(client, "client");
this.instanceRemoved = checkNotNull(instanceRemoved, "instanceRemoved");
}
@Override
public boolean execute(String id) {
/*
* TODO: implement
*/
return false;
client.deleteInstance(id);
return instanceRemoved.apply(client.getInstance(id));
}
}
@Provides
@ -214,13 +322,17 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
@Provides
@Singleton
Location getDefaultLocation(Set<? extends Location> locations) {
Location getDefaultLocation(
@Named(PROPERTY_IBMDEVELOPERCLOUD_LOCATION) final String defaultLocation,
Set<? extends Location> locations) {
return Iterables.find(locations, new Predicate<Location>() {
/*
* TODO: implement
*/
@Override
public boolean apply(Location input) {
return input.getId().equals(defaultLocation);
}
return null;
});
}
@Provides
@ -229,10 +341,10 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
final Set<Location> assignableLocations = Sets.newHashSet();
holder.logger.debug(">> providing locations");
Location parent = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
/*
* TODO: add children with parent to locations. Note do not add parent to assignablelocations
* directly
*/
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations())
assignableLocations.add(new LocationImpl(LocationScope.ZONE, location.getId(), location
.getName(), parent));
holder.logger.debug("<< locations(%d)", assignableLocations.size());
return assignableLocations;
@ -240,34 +352,103 @@ public class IBMDeveloperCloudComputeServiceContextModule extends IBMDeveloperCl
@Provides
@Singleton
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync,
Set<? extends Image> images, LogHolder holder) {
protected Set<? extends Size> provideSizes(IBMDeveloperCloudClient sync, LogHolder holder,
Map<String, ? extends Location> locations) {
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
/*
* TODO: implement
*/
for (org.jclouds.ibmdev.domain.Location location : sync.listLocations()) {
Location assignedLocation = locations.get(location.getId());
// TODO we cannot query actual size, yet, so lets make the multipliers work out
int sizeMultiplier = 1;
for (String i386 : location.getCapabilities().get(
IBMDeveloperCloudConstants.CAPABILITY_I386).keySet())
sizes.add(buildSize(location, i386, assignedLocation, sizeMultiplier++));
for (String x86_64 : location.getCapabilities().get(
IBMDeveloperCloudConstants.CAPABILITY_x86_64).keySet())
sizes.add(buildSize(location, x86_64, assignedLocation, sizeMultiplier++));
}
holder.logger.debug("<< sizes(%d)", sizes.size());
return sizes;
}
private SizeImpl buildSize(org.jclouds.ibmdev.domain.Location location, final String id,
Location assignedLocation, int multiplier) {
return new SizeImpl(id, id, location.getId() + "/" + id, assignedLocation, null, ImmutableMap
.<String, String> of(), multiplier, multiplier * 1024, multiplier * 10,
new Predicate<Image>() {
@Override
public boolean apply(Image input) {
if (input instanceof IBMImage)
return IBMImage.class.cast(input).rawImage.getSupportedInstanceTypes()
.contains(id);
return false;
}
});
}
@Provides
@Singleton
protected Map<String, ? extends Image> provideImageMap(Set<? extends Image> locations) {
return Maps.uniqueIndex(locations, new Function<Image, String>() {
@Override
public String apply(Image from) {
return from.getId();
}
});
}
@Provides
@Singleton
protected Map<String, ? extends Location> provideLocationMap(Set<? extends Location> locations) {
return Maps.uniqueIndex(locations, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
}
@Provides
@Singleton
protected Set<? extends Image> provideImages(final IBMDeveloperCloudClient sync,
LogHolder holder, Location location) {
LogHolder holder, Map<String, ? extends Location> locations) {
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
/*
* TODO: implement
*/
for (org.jclouds.ibmdev.domain.Image image : sync.listImages())
images.add(new IBMImage(image, locations.get(image.getLocation())));
holder.logger.debug("<< images(%d)", images.size());
return images;
}
private static class IBMImage extends ImageImpl {
/** The serialVersionUID */
private static final long serialVersionUID = -8520373150950058296L;
private final org.jclouds.ibmdev.domain.Image rawImage;
public IBMImage(org.jclouds.ibmdev.domain.Image in, Location location) {
// TODO parse correct OS
// TODO manifest fails to parse due to encoding issues in the path
super(in.getId(), in.getName(), in.getId(), location, null, ImmutableMap
.<String, String> of(), in.getDescription(), in.getCreatedTime().getTime() + "",
(in.getPlatform().indexOf("Redhat") != -1) ? OsFamily.RHEL : OsFamily.SUSE, in
.getPlatform(),
(in.getPlatform().indexOf("32") != -1) ? Architecture.X86_32
: Architecture.X86_64, null);
this.rawImage = in;
}
}
@Singleton
private static class LogHolder {
@Resource

View File

@ -20,6 +20,7 @@ package org.jclouds.ibmdev.config;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import javax.inject.Named;
import javax.inject.Singleton;
@ -36,11 +37,16 @@ import org.jclouds.http.functions.config.ParserModule.LongDateAdapter;
import org.jclouds.ibmdev.IBMDeveloperCloud;
import org.jclouds.ibmdev.IBMDeveloperCloudAsyncClient;
import org.jclouds.ibmdev.IBMDeveloperCloudClient;
import org.jclouds.ibmdev.domain.Instance;
import org.jclouds.ibmdev.handlers.IBMDeveloperCloudErrorHandler;
import org.jclouds.ibmdev.predicates.InstanceActive;
import org.jclouds.ibmdev.predicates.InstanceRemovedOrNotFound;
import org.jclouds.ibmdev.reference.IBMDeveloperCloudConstants;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.base.Predicate;
import com.google.inject.Provides;
/**
@ -90,4 +96,17 @@ public class IBMDeveloperCloudRestClientModule extends
super.configure();
}
@Provides
@Singleton
@Named("ACTIVE")
protected Predicate<Instance> instanceActive(InstanceActive instanceActive) {
return new RetryablePredicate<Instance>(instanceActive, 600, 1, TimeUnit.SECONDS);
}
@Provides
@Singleton
@Named("REMOVED")
Predicate<Instance> instanceRemoved(InstanceRemovedOrNotFound instanceRemoved) {
return new RetryablePredicate<Instance>(instanceRemoved, 5000, 500, TimeUnit.MILLISECONDS);
}
}

View File

@ -27,14 +27,39 @@ import javax.annotation.Nullable;
* @author Adrian Cole
*/
public class Address {
private int state;
private int location;
private String ip;
private long id;
@Nullable
private Long instanceId;
public Address(int state, int location, String ip, long id, Long instanceId) {
public static enum State {
NEW, ALLOCATING, FREE, ATTACHED, RELEASING, RELEASED, FAILED;
public static State fromValue(int v) {
switch (v) {
case 0:
return NEW;
case 1:
return ALLOCATING;
case 2:
return FREE;
case 3:
return ATTACHED;
case 4:
return RELEASING;
case 5:
return RELEASED;
case 6:
return FAILED;
default:
throw new IllegalArgumentException("invalid state:" + v);
}
}
}
private int state;
private String location;
private String ip;
private String id;
@Nullable
private String instanceId;
public Address(int state, String location, String ip, String id, String instanceId) {
this.state = state;
this.location = location;
this.ip = ip;
@ -46,19 +71,19 @@ public class Address {
}
public int getState() {
return state;
public State getState() {
return State.fromValue(state);
}
public void setState(int state) {
this.state = state;
}
public int getLocation() {
public String getLocation() {
return location;
}
public void setLocation(int location) {
public void setLocation(String location) {
this.location = location;
}
@ -70,19 +95,19 @@ public class Address {
this.ip = ip;
}
public long getId() {
public String getId() {
return id;
}
public void setId(long id) {
public void setId(String id) {
this.id = id;
}
public Long getInstanceId() {
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(Long instanceId) {
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
@ -90,11 +115,10 @@ public class Address {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((ip == null) ? 0 : ip.hashCode());
result = prime * result + location;
result = prime * result + state;
result = prime * result + ((location == null) ? 0 : location.hashCode());
return result;
}
@ -107,7 +131,10 @@ public class Address {
if (getClass() != obj.getClass())
return false;
Address other = (Address) obj;
if (id != other.id)
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (instanceId == null) {
if (other.instanceId != null)
@ -119,16 +146,17 @@ public class Address {
return false;
} else if (!ip.equals(other.ip))
return false;
if (location != other.location)
return false;
if (state != other.state)
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
return true;
}
@Override
public String toString() {
return "[id=" + id + ", ip=" + ip + ", location=" + location + ", state=" + state
return "[id=" + id + ", ip=" + ip + ", location=" + location + ", state=" + getState()
+ ", instanceId=" + instanceId + "]";
}

View File

@ -30,7 +30,28 @@ import com.google.common.collect.Sets;
* @author Adrian Cole
*/
public class Image {
public enum Visibility {
public static enum State {
NEW, AVAILABLE, UNAVAILABLE, DELETED, CAPTURING;
public static State fromValue(int v) {
switch (v) {
case 0:
return NEW;
case 1:
return AVAILABLE;
case 2:
return UNAVAILABLE;
case 3:
return DELETED;
case 4:
return CAPTURING;
default:
throw new IllegalArgumentException("invalid state:" + v);
}
}
}
public static enum Visibility {
PUBLIC,
@ -50,14 +71,14 @@ public class Image {
private String architecture;
private String platform;
private Date createdTime;
private long location;
private String location;
private Set<String> supportedInstanceTypes = Sets.newLinkedHashSet();
private Set<String> productCodes = Sets.newLinkedHashSet();
/**
* Note that this isn't a URI, as parsing fails due to IBM including '{' characters in the path.
*/
private String documentation;
private long id;
private String id;
private String description;
public String getName() {
@ -76,8 +97,8 @@ public class Image {
this.manifest = manifest;
}
public int getState() {
return state;
public State getState() {
return State.fromValue(state);
}
public void setState(int state) {
@ -124,11 +145,11 @@ public class Image {
this.createdTime = createdTime;
}
public long getLocation() {
public String getLocation() {
return location;
}
public void setLocation(long location) {
public void setLocation(String location) {
this.location = location;
}
@ -156,11 +177,11 @@ public class Image {
this.documentation = documentation;
}
public long getId() {
public String getId() {
return id;
}
public void setId(long id) {
public void setId(String id) {
this.id = id;
}
@ -180,14 +201,13 @@ public class Image {
result = prime * result + ((createdTime == null) ? 0 : createdTime.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((documentation == null) ? 0 : documentation.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + (int) (location ^ (location >>> 32));
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((manifest == null) ? 0 : manifest.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
result = prime * result + ((platform == null) ? 0 : platform.hashCode());
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
result = prime * result + state;
result = prime * result
+ ((supportedInstanceTypes == null) ? 0 : supportedInstanceTypes.hashCode());
result = prime * result + ((visibility == null) ? 0 : visibility.hashCode());
@ -223,9 +243,15 @@ public class Image {
return false;
} else if (!documentation.equals(other.documentation))
return false;
if (id != other.id)
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (location != other.location)
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (manifest == null) {
if (other.manifest != null)
@ -252,8 +278,6 @@ public class Image {
return false;
} else if (!productCodes.equals(other.productCodes))
return false;
if (state != other.state)
return false;
if (supportedInstanceTypes == null) {
if (other.supportedInstanceTypes != null)
return false;
@ -270,7 +294,7 @@ public class Image {
@Override
public String toString() {
return "Image [id=" + id + ", name=" + name + ", location=" + location + ", manifest="
+ manifest + ", platform=" + platform + ", state=" + state
+ manifest + ", platform=" + platform + ", state=" + getState()
+ ", supportedInstanceTypes=" + supportedInstanceTypes + ", visibility="
+ visibility + "]";
}

View File

@ -30,6 +30,40 @@ import com.google.common.collect.Sets;
* @author Adrian Cole
*/
public class Instance {
public static enum Status {
NEW, PROVISIONING, FAILED, REMOVED, REJECTED, ACTIVE, UNKNOWN, DEPROVISIONING, RESTARTING, STARTING, STOPPING, STOPPED;
public static Status fromValue(int v) {
switch (v) {
case 0:
return NEW;
case 1:
return PROVISIONING;
case 2:
return FAILED;
case 3:
return REMOVED;
case 4:
return REJECTED;
case 5:
return ACTIVE;
case 6:
return UNKNOWN;
case 7:
return DEPROVISIONING;
case 8:
return RESTARTING;
case 9:
return STARTING;
case 10:
return STOPPING;
case 11:
return STOPPED;
default:
throw new IllegalArgumentException("invalid state:" + v);
}
}
}
public static class Software {
private String version;
private String type;
@ -115,24 +149,24 @@ public class Instance {
private Date launchTime;
private Set<Software> software = Sets.newLinkedHashSet();
private String ip;
private long requestId;
private String requestId;
private String keyName;
private String name;
private String instanceType;
private int status;
private String owner;
private String hostname;
private int location;
private long imageId;
private String location;
private String imageId;
private Set<String> productCodes;
private String requestName;
private long id;
private String id;
private Date expirationTime;
public Instance(Date launchTime, Set<Software> software, String ip, long requestId,
public Instance(Date launchTime, Set<Software> software, String ip, String requestId,
String keyName, String name, String instanceType, int status, String owner,
String hostname, int location, long imageId, Set<String> productCodes,
String requestName, long id, Date expirationTime) {
String hostname, String location, String imageId, Set<String> productCodes,
String requestName, String id, Date expirationTime) {
this.launchTime = launchTime;
this.software = software;
this.ip = ip;
@ -178,11 +212,11 @@ public class Instance {
this.ip = ip;
}
public long getRequestId() {
public String getRequestId() {
return requestId;
}
public void setRequestId(long requestId) {
public void setRequestId(String requestId) {
this.requestId = requestId;
}
@ -210,8 +244,8 @@ public class Instance {
this.instanceType = instanceType;
}
public int getStatus() {
return status;
public Status getStatus() {
return Status.fromValue(status);
}
public void setStatus(int status) {
@ -234,19 +268,19 @@ public class Instance {
this.hostname = hostname;
}
public int getLocation() {
public String getLocation() {
return location;
}
public void setLocation(int location) {
public void setLocation(String location) {
this.location = location;
}
public long getImageId() {
public String getImageId() {
return imageId;
}
public void setImageId(long imageId) {
public void setImageId(String imageId) {
this.imageId = imageId;
}
@ -266,11 +300,11 @@ public class Instance {
this.requestName = requestName;
}
public long getId() {
public String getId() {
return id;
}
public void setId(long id) {
public void setId(String id) {
this.id = id;
}
@ -286,22 +320,20 @@ public class Instance {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((expirationTime == null) ? 0 : expirationTime.hashCode());
result = prime * result + ((hostname == null) ? 0 : hostname.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + (int) imageId;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
result = prime * result + ((ip == null) ? 0 : ip.hashCode());
result = prime * result + ((keyName == null) ? 0 : keyName.hashCode());
result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode());
result = prime * result + location;
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
result = prime * result + (int) (requestId ^ (requestId >>> 32));
result = prime * result + ((requestId == null) ? 0 : requestId.hashCode());
result = prime * result + ((requestName == null) ? 0 : requestName.hashCode());
result = prime * result + ((software == null) ? 0 : software.hashCode());
result = prime * result + status;
return result;
}
@ -314,19 +346,20 @@ public class Instance {
if (getClass() != obj.getClass())
return false;
Instance other = (Instance) obj;
if (expirationTime == null) {
if (other.expirationTime != null)
return false;
} else if (!expirationTime.equals(other.expirationTime))
return false;
if (hostname == null) {
if (other.hostname != null)
return false;
} else if (!hostname.equals(other.hostname))
return false;
if (id != other.id)
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (imageId != other.imageId)
if (imageId == null) {
if (other.imageId != null)
return false;
} else if (!imageId.equals(other.imageId))
return false;
if (instanceType == null) {
if (other.instanceType != null)
@ -348,7 +381,10 @@ public class Instance {
return false;
} else if (!launchTime.equals(other.launchTime))
return false;
if (location != other.location)
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (name == null) {
if (other.name != null)
@ -365,7 +401,10 @@ public class Instance {
return false;
} else if (!productCodes.equals(other.productCodes))
return false;
if (requestId != other.requestId)
if (requestId == null) {
if (other.requestId != null)
return false;
} else if (!requestId.equals(other.requestId))
return false;
if (requestName == null) {
if (other.requestName != null)
@ -377,18 +416,16 @@ public class Instance {
return false;
} else if (!software.equals(other.software))
return false;
if (status != other.status)
return false;
return true;
}
@Override
public String toString() {
return "Instance [id=" + id + ", name=" + name + ", ip=" + ip + ", hostname=" + hostname
+ ", status=" + status + ", instanceType=" + instanceType + ", location=" + location
+ ", imageId=" + imageId + ", software=" + software + ", keyName=" + keyName
+ ", launchTime=" + launchTime + ", expirationTime=" + expirationTime + ", owner="
+ owner + ", productCodes=" + productCodes + ", requestId=" + requestId
+ ", status=" + getStatus() + ", instanceType=" + instanceType + ", location="
+ location + ", imageId=" + imageId + ", software=" + software + ", keyName="
+ keyName + ", launchTime=" + launchTime + ", expirationTime=" + expirationTime
+ ", owner=" + owner + ", productCodes=" + productCodes + ", requestId=" + requestId
+ ", requestName=" + requestName + "]";
}

View File

@ -34,13 +34,13 @@ import com.google.gson.annotations.SerializedName;
public class Key {
@SerializedName("default")
private boolean isDefault;
private Set<Long> instanceIds = Sets.newLinkedHashSet();
private Set<String> instanceIds = Sets.newLinkedHashSet();
private String keyMaterial;
@SerializedName("keyName")
private String name;
private Date lastModifiedTime;
public Key(boolean isDefault, Iterable<Long> instanceIds, String keyMaterial, String name,
public Key(boolean isDefault, Iterable<String> instanceIds, String keyMaterial, String name,
Date lastModifiedTime) {
this.isDefault = isDefault;
Iterables.addAll(this.instanceIds, instanceIds);
@ -137,11 +137,11 @@ public class Key {
+ ", keyMaterial=" + keyMaterial + ", lastModifiedTime=" + lastModifiedTime + "]";
}
public Set<Long> getInstanceIds() {
public Set<String> getInstanceIds() {
return instanceIds;
}
public void setInstanceIds(Set<Long> instanceIds) {
public void setInstanceIds(Set<String> instanceIds) {
this.instanceIds = instanceIds;
}

View File

@ -30,13 +30,13 @@ import com.google.common.collect.Maps;
*/
public class Location {
private final int id;
private final String id;
private final String name;
private final String description;
private final String location;
private final Map<String, Map<String, String>> capabilities = Maps.newLinkedHashMap();
public Location(int id, String name, String description, String location,
public Location(String id, String name, String description, String location,
Map<String, Map<String, String>> capabilities) {
this.id = id;
this.name = name;
@ -45,7 +45,7 @@ public class Location {
this.capabilities.putAll(capabilities);
}
public int getId() {
public String getId() {
return id;
}
@ -71,7 +71,7 @@ public class Location {
int result = 1;
result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + id;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
@ -96,7 +96,10 @@ public class Location {
return false;
} else if (!description.equals(other.description))
return false;
if (id != other.id)
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (location == null) {
if (other.location != null)

View File

@ -32,19 +32,43 @@ import com.google.common.collect.Sets;
*/
public class Volume {
private Long instanceId;
public static enum State {
NEW, CREATING, DELETING, DELETED, UNMOUNTED, MOUNTED, FAILED;
public static State fromValue(int v) {
switch (v) {
case 0:
return NEW;
case 1:
return CREATING;
case 2:
return DELETING;
case 3:
return DELETED;
case 4:
return UNMOUNTED;
case 5:
return MOUNTED;
case 6:
return FAILED;
default:
throw new IllegalArgumentException("invalid state:" + v);
}
}
}
private String instanceId;
private int state;
private int size;
private String owner;
private Date createdTime;
private int location;
private String location;
private Set<String> productCodes = Sets.newLinkedHashSet();
private String format;
private String name;
private long id;
private String id;
public Volume(Long instanceId, int state, int size, String owner, Date createdTime,
int location, Iterable<String> productCodes, String format, String name, long id) {
public Volume(String instanceId, int state, int size, String owner, Date createdTime,
String location, Iterable<String> productCodes, String format, String name, String id) {
this.instanceId = instanceId;
this.state = state;
this.size = size;
@ -61,16 +85,16 @@ public class Volume {
}
public Long getInstanceId() {
public String getInstanceId() {
return instanceId;
}
public void setInstanceId(Long instanceId) {
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public int getState() {
return state;
public State getState() {
return State.fromValue(state);
}
public void setState(int state) {
@ -101,11 +125,11 @@ public class Volume {
this.createdTime = createdTime;
}
public int getLocation() {
public String getLocation() {
return location;
}
public void setLocation(int location) {
public void setLocation(String location) {
this.location = location;
}
@ -133,11 +157,11 @@ public class Volume {
this.name = name;
}
public long getId() {
public String getId() {
return id;
}
public void setId(long id) {
public void setId(String id) {
this.id = id;
}
@ -147,14 +171,13 @@ public class Volume {
int result = 1;
result = prime * result + ((createdTime == null) ? 0 : createdTime.hashCode());
result = prime * result + ((format == null) ? 0 : format.hashCode());
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + location;
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((owner == null) ? 0 : owner.hashCode());
result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode());
result = prime * result + size;
result = prime * result + state;
return result;
}
@ -177,14 +200,20 @@ public class Volume {
return false;
} else if (!format.equals(other.format))
return false;
if (id != other.id)
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (instanceId == null) {
if (other.instanceId != null)
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (location != other.location)
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (name == null) {
if (other.name != null)
@ -203,14 +232,12 @@ public class Volume {
return false;
if (size != other.size)
return false;
if (state != other.state)
return false;
return true;
}
@Override
public String toString() {
return "[id=" + id + ", name=" + name + ", size=" + size + ", state=" + state
return "[id=" + id + ", name=" + name + ", size=" + size + ", state=" + getState()
+ ", instanceId=" + instanceId + ", location=" + location + ", format=" + format
+ ", owner=" + owner + ", createdTime=" + createdTime + ", productCodes="
+ productCodes + "]";

View File

@ -66,7 +66,9 @@ public class ParseAddressFromJson extends ParseJson<Address> {
@Override
protected Address apply(InputStream stream) {
try {
return gson.fromJson(new InputStreamReader(stream, "UTF-8"), Address.class);
Address returnVal = gson.fromJson(new InputStreamReader(stream, "UTF-8"), Address.class);
ParseUtils.CLEAN_ADDRESS.apply(returnVal);
return returnVal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}

View File

@ -72,7 +72,8 @@ public class ParseAddressesFromJson extends ParseJson<Set<? extends Address>> {
@Override
protected Set<? extends Address> apply(InputStream stream) {
try {
return gson.fromJson(new InputStreamReader(stream, "UTF-8"), AddressListResponse.class).addresses;
return ParseUtils.clean(gson.fromJson(new InputStreamReader(stream, "UTF-8"),
AddressListResponse.class).addresses, ParseUtils.CLEAN_ADDRESS);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}

View File

@ -44,7 +44,6 @@ package org.jclouds.ibmdev.functions;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -52,7 +51,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Image;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
/**
@ -65,14 +63,11 @@ public class ParseImageFromJson extends ParseJson<Image> {
super(gson);
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Image apply(InputStream stream) {
try {
Image returnVal = gson.fromJson(new InputStreamReader(stream, "UTF-8"), Image.class);
if (emptyString.equals(returnVal.getProductCodes()))
returnVal.getProductCodes().clear();
ParseUtils.CLEAN_IMAGE.apply(returnVal);
return returnVal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -52,7 +52,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Image;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
@ -70,17 +69,11 @@ public class ParseImagesFromJson extends ParseJson<Set<? extends Image>> {
Set<Image> images = Sets.newLinkedHashSet();
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Set<? extends Image> apply(InputStream stream) {
try {
Set<Image> list = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
ImageListResponse.class).images;
for (Image image : list)
if (emptyString.equals(image.getProductCodes()))
image.getProductCodes().clear();
return list;
return ParseUtils.clean(gson.fromJson(new InputStreamReader(stream, "UTF-8"),
ImageListResponse.class).images, ParseUtils.CLEAN_IMAGE);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}

View File

@ -44,7 +44,6 @@ package org.jclouds.ibmdev.functions;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -52,7 +51,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Instance;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
/**
@ -65,14 +63,11 @@ public class ParseInstanceFromJson extends ParseJson<Instance> {
super(gson);
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Instance apply(InputStream stream) {
try {
Instance returnVal = gson.fromJson(new InputStreamReader(stream, "UTF-8"), Instance.class);
if (emptyString.equals(returnVal.getProductCodes()))
returnVal.getProductCodes().clear();
ParseUtils.CLEAN_INSTANCE.apply(returnVal);
return returnVal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -52,7 +52,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Instance;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
@ -70,17 +69,11 @@ public class ParseInstancesFromJson extends ParseJson<Set<? extends Instance>> {
Set<Instance> instances = Sets.newLinkedHashSet();
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Set<? extends Instance> apply(InputStream stream) {
try {
Set<Instance> list = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
InstanceListResponse.class).instances;
for (Instance instance : list)
if (emptyString.equals(instance.getProductCodes()))
instance.getProductCodes().clear();
return list;
return ParseUtils.clean(gson.fromJson(new InputStreamReader(stream, "UTF-8"),
InstanceListResponse.class).instances, ParseUtils.CLEAN_INSTANCE);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}

View File

@ -21,7 +21,6 @@ package org.jclouds.ibmdev.functions;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -29,7 +28,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Volume;
import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson;
/**
@ -42,14 +40,11 @@ public class ParseVolumeFromJson extends ParseJson<Volume> {
super(gson);
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Volume apply(InputStream stream) {
try {
Volume returnVal = gson.fromJson(new InputStreamReader(stream, "UTF-8"), Volume.class);
if (emptyString.equals(returnVal.getProductCodes()))
returnVal.getProductCodes().clear();
ParseUtils.CLEAN_VOLUME.apply(returnVal);
return returnVal;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -29,7 +29,6 @@ import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.ibmdev.domain.Volume;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
@ -47,17 +46,11 @@ public class ParseVolumesFromJson extends ParseJson<Set<? extends Volume>> {
Set<Volume> volumes = Sets.newLinkedHashSet();
}
private static final Set<String> emptyString = ImmutableSet.of("");
@Override
protected Set<? extends Volume> apply(InputStream stream) {
try {
Set<Volume> list = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
VolumeListResponse.class).volumes;
for (Volume volume : list)
if (emptyString.equals(volume.getProductCodes()))
volume.getProductCodes().clear();
return list;
return ParseUtils.clean(gson.fromJson(new InputStreamReader(stream, "UTF-8"),
VolumeListResponse.class).volumes, ParseUtils.CLEAN_VOLUME);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e);
}

View File

@ -56,6 +56,9 @@ public class IBMDeveloperCloudErrorHandler implements HttpErrorHandler {
.getRequestLine(), response.getStatusLine());
switch (response.getStatusCode()) {
case 401:
exception = new AuthorizationException(command.getRequest(),
message != null ? message : response.getStatusLine());
break;
case 402:
case 403:
exception = new AuthorizationException(message, exception);

View File

@ -18,15 +18,9 @@
*/
package org.jclouds.ibmdev.options;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.Maps;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
*
@ -34,29 +28,11 @@ import com.google.common.collect.Maps;
* @author Adrian Cole
*
*/
public class CreateInstanceOptions extends BindToJsonPayload {
Long volumeID;
Long ip;
String publicKey = "DEFAULT";
Map<String, String> configurationData = Maps.newLinkedHashMap();
public class CreateInstanceOptions extends BaseHttpRequestOptions {
@Override
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
Map<String, Object> postData = Maps.newLinkedHashMap();
postData.putAll(postParams);
postData.put("publicKey", publicKey);
if (volumeID != null)
postData.put("volumeID", volumeID);
if (configurationData.size() > 0)
postData.put("configurationData", configurationData);
if (ip != null)
postData.put("ip", ip);
super.bindToRequest(request, postData);
}
@Override
public void bindToRequest(HttpRequest request, Object toBind) {
throw new IllegalStateException("CreateInstance is a POST operation");
public CreateInstanceOptions() {
super();
formParameters.put("publicKey", "DEFAULT");
}
/**
@ -66,11 +42,15 @@ public class CreateInstanceOptions extends BindToJsonPayload {
* @param mountPoint
* The mount point in which to mount the attached storage volume
*/
public CreateInstanceOptions mountVolume(long id, String mountPoint) {
checkArgument(id > 0, "volume id must be a positive number");
public CreateInstanceOptions mountVolume(String id, String mountPoint) {
checkNotNull(id, "volume id");
checkNotNull(mountPoint, "mountPoint");
this.volumeID = id;
configurationData.put(String.format("oss.storage.id.%d.mnt", id), mountPoint);
formParameters.removeAll("volumeID");
formParameters.put("volumeID", id + "");
String mountParam = String.format("oss.storage.id.%s.mnt", id);
formParameters.removeAll(mountParam);
formParameters.put(mountParam, mountPoint);
return this;
}
@ -81,7 +61,8 @@ public class CreateInstanceOptions extends BindToJsonPayload {
*/
public CreateInstanceOptions authorizePublicKey(String publicKeyName) {
checkNotNull(publicKeyName, "publicKeyName");
this.publicKey = publicKeyName;
formParameters.removeAll("publicKey");
formParameters.put("publicKey", publicKeyName);
return this;
}
@ -90,26 +71,27 @@ public class CreateInstanceOptions extends BindToJsonPayload {
* @param id
* The ID of a static IP address to associate with this instance
*/
public CreateInstanceOptions attachIp(long id) {
checkArgument(id > 0, "ip id must be a positive number");
this.ip = id;
public CreateInstanceOptions attachIp(String id) {
checkNotNull(id, "ip");
formParameters.removeAll("ip");
formParameters.put("ip", id + "");
return this;
}
public static class Builder {
/**
* @see CreateInstanceOptions#mountVolume(long, String )
* @see CreateInstanceOptions#mountVolume(String, String )
*/
public static CreateInstanceOptions mountVolume(long id, String mountPoint) {
public static CreateInstanceOptions mountVolume(String id, String mountPoint) {
CreateInstanceOptions options = new CreateInstanceOptions();
return options.mountVolume(id, mountPoint);
}
/**
* @see CreateInstanceOptions#attachIp(long )
* @see CreateInstanceOptions#attachIp(String )
*/
public static CreateInstanceOptions attachIp(long id) {
public static CreateInstanceOptions attachIp(String id) {
CreateInstanceOptions options = new CreateInstanceOptions();
return options.attachIp(id);
}

View File

@ -20,12 +20,7 @@ package org.jclouds.ibmdev.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.binders.BindToJsonPayload;
import com.google.common.collect.Maps;
import org.jclouds.http.options.BaseHttpRequestOptions;
/**
*
@ -33,23 +28,7 @@ import com.google.common.collect.Maps;
* @author Adrian Cole
*
*/
public class RestartInstanceOptions extends BindToJsonPayload {
String keyName;
@Override
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
Map<String, Object> postData = Maps.newLinkedHashMap();
postData.putAll(postParams);
postData.put("state", "restart");
if (keyName != null)
postData.put("keyName", keyName);
super.bindToRequest(request, postData);
}
@Override
public void bindToRequest(HttpRequest request, Object toBind) {
throw new IllegalStateException("RestartInstance is a PUT operation");
}
public class RestartInstanceOptions extends BaseHttpRequestOptions {
/**
*
@ -58,7 +37,8 @@ public class RestartInstanceOptions extends BindToJsonPayload {
*/
public RestartInstanceOptions authorizePublicKey(String keyName) {
checkNotNull(keyName, "keyName");
this.keyName = keyName;
formParameters.removeAll("keyName");
formParameters.put("keyName", keyName);
return this;
}

View File

@ -47,11 +47,13 @@ package org.jclouds.ibmdev.reference;
* @author Adrian Cole
*/
public interface IBMDeveloperCloudConstants {
public static final String PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT = "jclouds.ibmdevelopercloud.endpoint";
public static final String PROPERTY_IBMDEVELOPERCLOUD_USER = "jclouds.ibmdevelopercloud.user";
public static final String PROPERTY_IBMDEVELOPERCLOUD_PASSWORD = "jclouds.ibmdevelopercloud.password";
public static final String PROPERTY_IBMDEVELOPERCLOUD_ENDPOINT = "jclouds.ibmdev.endpoint";
public static final String PROPERTY_IBMDEVELOPERCLOUD_USER = "jclouds.ibmdev.user";
public static final String PROPERTY_IBMDEVELOPERCLOUD_PASSWORD = "jclouds.ibmdev.password";
public static final String CAPABILITY_CAPACITY = "oss.storage.capacity";
public static final String CAPABILITY_FORMAT = "oss.storage.format";
public static final String CAPABILITY_I386 = "oss.instance.spec.i386";
public static final String CAPABILITY_x86_64 = "oss.instance.spec.x86_64";
public static final String PROPERTY_IBMDEVELOPERCLOUD_LOCATION= "jclouds.ibmdev.location";
}

View File

@ -36,7 +36,7 @@ import com.google.common.collect.Maps;
public class LocationHandler extends ParseSax.HandlerWithResult<Location> {
private StringBuilder currentText = new StringBuilder();
private int id;
private String id;
private String name;
private String description;
private String location;
@ -67,7 +67,7 @@ public class LocationHandler extends ParseSax.HandlerWithResult<Location> {
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("ID")) {
id = Integer.parseInt(currentText.toString().trim());
id = currentText.toString().trim();
} else if (qName.equalsIgnoreCase("Name")) {
name = currentText.toString().trim();
} else if (qName.equalsIgnoreCase("Description")) {
@ -79,7 +79,7 @@ public class LocationHandler extends ParseSax.HandlerWithResult<Location> {
} else if (qName.equalsIgnoreCase("Location")) {
if (currentText.toString().trim().equals("")) {
this.loc = new Location(id, name, description, location, capabilities);
id = 0;
id = null;
name = null;
description = null;
location = null;

View File

@ -100,9 +100,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testGetImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getImage", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getImage", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"GET https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/images/1 HTTP/1.1");
@ -118,9 +118,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testDeleteImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteImage", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteImage", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"DELETE https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/images/1 HTTP/1.1");
@ -138,15 +138,15 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
public void testSetImageVisibility() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("setImageVisibility",
long.class, Image.Visibility.class);
String.class, Image.Visibility.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1, Image.Visibility.PUBLIC);
method, "1", Image.Visibility.PUBLIC);
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/images/1 HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 23\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"visibility\":\"PUBLIC\"}");
"Accept: application/json\nContent-Length: 17\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "visibility=PUBLIC");
assertResponseParserClassEquals(method, httpRequest, ParseImageFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -177,9 +177,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
public void testListInstancesFromRequest() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("listInstancesFromRequest",
long.class);
String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1l);
method, "1");
assertRequestLineEquals(httpRequest,
"GET https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/requests/1 HTTP/1.1");
@ -195,9 +195,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testGetInstance() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getInstance", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getInstance", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"GET https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
@ -215,15 +215,15 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
public void testExtendReservationForInstance() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("extendReservationForInstance",
long.class, Date.class);
String.class, Date.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1, new Date(123215235l));
method, "1", new Date(123215235l));
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 28\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"expirationTime\":123215235}");
"Accept: application/json\nContent-Length: 24\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "expirationTime=123215235");
assertResponseParserClassEquals(method, httpRequest, ParseExpirationTimeFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -233,16 +233,16 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testRestartInstance() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("restartInstance", long.class,
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("restartInstance", String.class,
RestartInstanceOptions[].class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 19\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"state\":\"restart\"}");
"Accept: application/json\nContent-Length: 13\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "state=restart");
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -250,18 +250,19 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
checkFilters(httpRequest);
}
public void testRestartInstanceNewKey() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("restartInstance", long.class,
public void testRestartInstanceNewKey() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("restartInstance", String.class,
RestartInstanceOptions[].class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1, new RestartInstanceOptions().authorizePublicKey("keyName"));
method, "1", new RestartInstanceOptions().authorizePublicKey("keyName"));
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 39\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"state\":\"restart\",\"keyName\":\"keyName\"}");
"Accept: application/json\nContent-Length: 29\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "state=restart&keyName=keyName");
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -269,18 +270,19 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
checkFilters(httpRequest);
}
public void testSaveInstanceToImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("saveInstanceToImage", long.class,
String.class,String.class);
public void testSaveInstanceToImage() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("saveInstanceToImage",
String.class, String.class, String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1, "imageName", "imageDescription");
method, "1", "imageName", "imageDescription");
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 68\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"description\":\"imageDescription\",\"name\":\"imageName\",\"state\":\"save\"}");
"Accept: application/json\nContent-Length: 54\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "state=save&description=imageDescription&name=imageName");
assertResponseParserClassEquals(method, httpRequest, ParseImageFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -290,9 +292,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testDeleteInstance() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteInstance", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteInstance", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"DELETE https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances/1 HTTP/1.1");
@ -351,8 +353,8 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/keys HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 14\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"name\":\"key\"}");
"Accept: application/json\nContent-Length: 8\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "name=key");
assertResponseParserClassEquals(method, httpRequest, ParseKeyFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -371,8 +373,8 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/keys HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 39\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"publicKey\":\"publicbits\",\"name\":\"key\"}");
"Accept: application/json\nContent-Length: 29\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "name=key&publicKey=publicbits");
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -391,8 +393,8 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/keys/key HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 26\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"publicKey\":\"publicbits\"}");
"Accept: application/json\nContent-Length: 20\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "publicKey=publicbits");
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -412,8 +414,8 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"PUT https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/keys/key HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 18\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"default\":\"true\"}");
"Accept: application/json\nContent-Length: 12\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "default=true");
assertResponseParserClassEquals(method, httpRequest, CloseContentAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -460,9 +462,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testGetVolume() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getVolume", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getVolume", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"GET https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/storage/1 HTTP/1.1");
@ -487,9 +489,8 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/storage HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 69\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest,
"{\"location\":\"location\",\"name\":\"name\",\"format\":\"format\",\"size\":\"size\"}");
"Accept: application/json\nContent-Length: 51\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "location=location&format=format&name=name&size=size");
assertResponseParserClassEquals(method, httpRequest, ParseVolumeFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -505,16 +506,13 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
String.class, String.class, String.class, String.class,
CreateInstanceOptions[].class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, "location", "name", "imageID", "instanceType");
method, "1", "name", "22", "instanceType");
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 109\nContent-Type: application/json\n");
assertPayloadEquals(
httpRequest,
"{\"instanceType\":\"instanceType\",\"imageID\":\"imageID\",\"location\":\"location\",\"name\":\"name\",\"publicKey\":\"DEFAULT\"}");
"Accept: application/json\nContent-Length: 57\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "location=1&imageID=22&name=name&instanceType=instanceType");
assertResponseParserClassEquals(method, httpRequest, ParseInstanceFromJson.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -529,16 +527,16 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
String.class, String.class, String.class, String.class,
CreateInstanceOptions[].class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, "location", "name", "imageID", "instanceType", new CreateInstanceOptions()
.attachIp(1l).authorizePublicKey("MOO").mountVolume(2l, "/mnt"));
method, "location", "name", "22", "instanceType", new CreateInstanceOptions()
.attachIp("1").authorizePublicKey("MOO").mountVolume("2", "/mnt"));
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/instances HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 177\nContent-Type: application/json\n");
"Accept: application/json\nContent-Length: 122\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(
httpRequest,
"{\"instanceType\":\"instanceType\",\"imageID\":\"imageID\",\"location\":\"location\",\"name\":\"name\",\"publicKey\":\"MOO\",\"volumeID\":2,\"configurationData\":{\"oss.storage.id.2.mnt\":\"/mnt\"},\"ip\":1}");
"location=location&imageID=22&name=name&instanceType=instanceType&ip=1&publicKey=MOO&volumeID=2&oss.storage.id.2.mnt=%2Fmnt");
assertResponseParserClassEquals(method, httpRequest, ParseInstanceFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -549,9 +547,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testDeleteVolume() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteVolume", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("deleteVolume", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"DELETE https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/storage/1 HTTP/1.1");
@ -585,9 +583,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testGetLocation() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getLocation", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("getLocation", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"GET https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/locations/1 HTTP/1.1");
@ -623,15 +621,15 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
public void testAllocateAddressInLocation() throws SecurityException, NoSuchMethodException,
IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("allocateAddressInLocation",
long.class);
String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"POST https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/addresses HTTP/1.1");
assertHeadersEqual(httpRequest,
"Accept: application/json\nContent-Length: 16\nContent-Type: application/json\n");
assertPayloadEquals(httpRequest, "{\"location\":\"1\"}");
"Accept: application/json\nContent-Length: 10\nContent-Type: application/x-www-form-urlencoded\n");
assertPayloadEquals(httpRequest, "location=1");
assertResponseParserClassEquals(method, httpRequest, ParseAddressFromJson.class);
assertSaxResponseParserClassEquals(method, null);
@ -642,9 +640,9 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
}
public void testReleaseAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("releaseAddress", long.class);
Method method = IBMDeveloperCloudAsyncClient.class.getMethod("releaseAddress", String.class);
GeneratedHttpRequest<IBMDeveloperCloudAsyncClient> httpRequest = processor.createRequest(
method, 1);
method, "1");
assertRequestLineEquals(httpRequest,
"DELETE https://www-180.ibm.com/cloud/enterprise/beta/api/rest/20090403/addresses/1 HTTP/1.1");

View File

@ -24,23 +24,39 @@
package org.jclouds.ibmdev;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.ibmdev.options.CreateInstanceOptions.Builder.attachIp;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.http.HttpResponseException;
import org.jclouds.ibmdev.domain.Address;
import org.jclouds.ibmdev.domain.Image;
import org.jclouds.ibmdev.domain.Instance;
import org.jclouds.ibmdev.domain.Key;
import org.jclouds.ibmdev.domain.Location;
import org.jclouds.ibmdev.domain.Volume;
import org.jclouds.ibmdev.domain.Instance.Software;
import org.jclouds.ibmdev.predicates.AddressFree;
import org.jclouds.ibmdev.predicates.VolumeUnmounted;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Charsets;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;
/**
* Tests behavior of {@code IBMDeveloperCloudClient}
@ -51,10 +67,19 @@ import com.google.common.collect.Iterables;
public class IBMDeveloperCloudClientLiveTest {
private IBMDeveloperCloudClient connection;
private Location location;
private Address ip;
private ImmutableMap<String, String> keyPair;
private Key key;
private Volume volume;
private Instance instance;
private String user;
private static final String TAG = System.getProperty("user.name");
@BeforeGroups(groups = { "live" })
public void setupClient() {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
connection = (IBMDeveloperCloudClient) IBMDeveloperCloudContextFactory.createContext(user,
@ -85,7 +110,7 @@ public class IBMDeveloperCloudClientLiveTest {
@Test
public void testListInstancesFromRequestReturnsNull() throws Exception {
Set<? extends Instance> response = connection.listInstancesFromRequest(Long.MAX_VALUE);
Set<? extends Instance> response = connection.listInstancesFromRequest(Long.MAX_VALUE+"");
assertNull(response);
}
@ -142,8 +167,8 @@ public class IBMDeveloperCloudClientLiveTest {
Set<? extends Location> response = connection.listLocations();
assertNotNull(response);
if (response.size() > 0) {
Location image = Iterables.get(response, 0);
assertEquals(connection.getLocation(image.getId()).getId(), image.getId());
location = Iterables.get(response, 0);
assertEquals(connection.getLocation(location.getId()).getId(), location.getId());
}
}
@ -153,4 +178,194 @@ public class IBMDeveloperCloudClientLiveTest {
assertNotNull(response);
}
@Test(dependsOnMethods = "testGetLocation")
public void testAddPublicKey() throws Exception {
try {
connection.addPublicKey(TAG, keyPair.get("public"));
} catch (IllegalStateException e) {
// must not have been found
connection.updatePublicKey(TAG, keyPair.get("public"));
}
key = connection.getKey(TAG);
assertEquals(key.getName(), TAG);
assertEquals(key.getInstanceIds(), ImmutableSet.<Long> of());
assert keyPair.get("public").indexOf(key.getKeyMaterial()) > 0;
assertNotNull(key.getLastModifiedTime());
}
@Test(dependsOnMethods = "testGetLocation")
public void testAllocateIpAddress() throws Exception {
try {
ip = connection.allocateAddressInLocation(location.getId());
assertEquals(ip.getIp(), null);
// wait up to 30 seconds for this to become "free"
assert new RetryablePredicate<Address>(new AddressFree(connection), 30, 2,
TimeUnit.SECONDS).apply(ip);
} catch (IllegalStateException e) {
if (HttpResponseException.class.cast(e.getCause()).getResponse().getStatusCode() == 409) {
ip = Iterables.find(connection.listAddresses(), new Predicate<Address>() {
@Override
public boolean apply(Address input) {
return input.getState() == Address.State.FREE;
}
});
} else {
throw e;
}
}
assertEquals(ip.getInstanceId(), "0");
assertEquals(ip.getLocation(), location.getId());
final String id = ip.getId();
Set<? extends Address> allAddresses = connection.listAddresses();
// refresh address as it may have been just created
ip = Iterables.find(allAddresses, new Predicate<Address>() {
@Override
public boolean apply(Address input) {
return input.getId().equals(id);
}
});
assert (allAddresses.contains(ip)) : String.format("ip %s not in %s", ip, allAddresses);
}
@Test(dependsOnMethods = "testGetLocation")
public void testCreateVolume() throws Exception {
try {
volume = connection.createVolumeInLocation(location.getId(), TAG, "EXT3", "SMALL");
// wait up to 5 minutes for this to become "unmounted"
assert new RetryablePredicate<Volume>(new VolumeUnmounted(connection), 300, 5,
TimeUnit.SECONDS).apply(volume);
} catch (IllegalStateException e) {
if (HttpResponseException.class.cast(e.getCause()).getResponse().getStatusCode() == 409) {
volume = Iterables.find(connection.listVolumes(), new Predicate<Volume>() {
@Override
public boolean apply(Volume input) {
return input.getState() == Volume.State.UNMOUNTED;
}
});
} else {
throw e;
}
}
assertEquals(volume.getInstanceId(), "0");
assertEquals(volume.getLocation(), location.getId());
final String id = volume.getId();
Set<? extends Volume> allVolumes = connection.listVolumes();
// refresh volume as it may have been just created
volume = Iterables.find(allVolumes, new Predicate<Volume>() {
@Override
public boolean apply(Volume input) {
return input.getId().equals(id);
}
});
assert (allVolumes.contains(volume)) : String.format("volume %s not in %s", volume, volume);
}
private static final String IMAGE_ID = "3";// RHEL
/**
* cannot run an instance due to 500 errors:
*
* http://www-180.ibm.com/cloud/enterprise/beta/ram/community/discussionTopic.faces?guid={
* DA689AEE-783C-6FE7-6F9F-DFEE9763F806}&v=1&fid=1068&tid=1523#topic
*/
@Test(expectedExceptions = HttpResponseException.class, dependsOnMethods = { "testAddPublicKey",
"testAllocateIpAddress", "testCreateVolume" })
public void testCreateInstanceWithOptions() throws Exception {
instance = connection.createInstanceInLocation(location.getId(), TAG, IMAGE_ID, "SMALL",
attachIp(ip.getId()).authorizePublicKey(key.getName()).mountVolume(volume.getId(),
"/mnt"));
assertEquals(instance.getLocation(), location.getId());
assertNotNull(instance.getHostname());
assertEquals(instance.getIp(), ip.getIp());
assertEquals(instance.getKeyName(), key.getName());
assertNotNull(instance.getExpirationTime());
assertNotNull(instance.getLaunchTime());
assertEquals(instance.getInstanceType(), "SMALL");
assertNotNull(instance.getName());
assertEquals(instance.getOwner(), user);
assertEquals(instance.getImageId(), IMAGE_ID);
assertEquals(instance.getSoftware(), ImmutableSet.<Software> of());
assertEquals(instance.getProductCodes(), ImmutableSet.<String> of());
assertEquals(instance.getStatus(), Instance.Status.NEW);
assertNotNull(instance.getRequestName());
volume = connection.getVolume(volume.getId());
assertEquals(volume.getInstanceId(), instance.getId());
refreshIp();
assertEquals(ip.getInstanceId(), ip.getId());
}
private void refreshIp() {
Set<? extends Address> allAddresses = connection.listAddresses();
final String id = ip.getId();
// refresh address as it may have been just created
ip = Iterables.find(allAddresses, new Predicate<Address>() {
@Override
public boolean apply(Address input) {
return input.getId().equals(id);
}
});
}
@AfterTest(groups = { "live" })
void tearDown() {
if (volume != null)
try {
connection.deleteVolume(volume.getId());
} catch (Exception e) {
}
if (ip != null)
try {
connection.releaseAddress(ip.getId());
} catch (Exception e) {
}
if (key != null)
try {
connection.deleteKey(key.getName());
} catch (Exception e) {
}
if (instance != null)
try {
connection.deleteInstance(instance.getId());
} catch (Exception e) {
}
}
@BeforeGroups(groups = { "live" })
protected void setupKeyPair() throws FileNotFoundException, IOException {
String secretKeyFile;
try {
secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
"jclouds.test.ssh.keyfile");
} catch (NullPointerException e) {
secretKeyFile = System.getProperty("user.home") + "/.ssh/id_rsa";
}
String secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
keyPair = ImmutableMap.<String, String> of("private", secret, "public", Files.toString(
new File(secretKeyFile + ".pub"), Charsets.UTF_8));
}
}

View File

@ -32,37 +32,36 @@ import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "ibmdevelopercloud.IBMDeveloperCloudComputeServiceLiveTest")
public class IBMDeveloperCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
@BeforeClass
@Override
public void setServiceDefaults() {
service = "ibmdevelopercloud";
}
@BeforeClass
@Override
public void setServiceDefaults() {
service = "ibmdev";
}
@Test
public void testTemplateBuilder() {
Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getArchitecture(), Architecture.X86_64);
assertEquals(defaultTemplate.getImage().getOsFamily(), OsFamily.UBUNTU);
assertEquals(defaultTemplate.getLocation().getId(), "DFW1");
assertEquals(defaultTemplate.getSize().getCores(), 1.0d);
}
@Test
public void testTemplateBuilder() {
Template defaultTemplate = client.templateBuilder().build();
assertEquals(defaultTemplate.getImage().getArchitecture(), Architecture.X86_32);
assertEquals(defaultTemplate.getImage().getOsFamily(), OsFamily.RHEL);
assertEquals(defaultTemplate.getLocation().getId(), "1");
assertEquals(defaultTemplate.getSize().getCores(), 2.0d);
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
@Override
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(service, user, password).getProviderSpecificContext();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<IBMDeveloperCloudClient, IBMDeveloperCloudAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(service, user, password).getProviderSpecificContext();
}
}
}

View File

@ -55,8 +55,7 @@ public class ParseAddressFromJsonTest {
}
public void test() {
Address address = new Address(2, 1, "129.33.196.243", 1217l, 1l);
Address address = new Address(2, "1", "129.33.196.243", "1217", "1");
Address compare = handler.apply(new HttpResponse(ParseAddressFromJsonTest.class
.getResourceAsStream("/address.json")));
assertEquals(compare, address);

View File

@ -54,8 +54,8 @@ public class ParseAddressesFromJsonTest {
}
public void test() {
Address address1 = new Address(2, 1, "129.33.196.243", 1217l, 1l);
Address address2 = new Address(3, 2, "129.33.196.244", 1218l, null);
Address address1 = new Address(2, "1", "129.33.196.243", "1217", "1");
Address address2 = new Address(3, "2", "129.33.196.244", "1218", null);
Set<? extends Address> compare = handler.apply(new HttpResponse(
ParseAddressesFromJsonTest.class.getResourceAsStream("/addresses.json")));
assert (compare.contains(address1));

View File

@ -69,12 +69,12 @@ public class ParseImageFromJsonTest {
image.setArchitecture("i386");
image.setPlatform("Redhat Enterprise Linux (32-bit)/5.4");
image.setCreatedTime(new Date(1265647398000l));
image.setLocation(1);
image.setLocation("1");
image.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
// image.setProductCodes();
image
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html");
image.setId(10005598);
image.setId("10005598");
image
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");

View File

@ -67,12 +67,12 @@ public class ParseImagesFromJsonTest {
image1.setArchitecture("i386");
image1.setPlatform("SUSE Linux Enterprise/10 SP2");
image1.setCreatedTime(new Date(1240632000000l));
image1.setLocation(1);
image1.setLocation("1");
image1.setSupportedInstanceTypes(ImmutableSet.of("SMALL", "MEDIUM", "LARGE"));
image1.setProductCodes(ImmutableSet.of("fd2d0478b132490897526b9b4433a334"));
image1
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{A233F5A0-05A5-F21D-3E92-3793B722DFBD}/1.0/GettingStarted.html");
image1.setId(2);
image1.setId("2");
image1
.setDescription("Rational Build Forge provides an adaptive process execution framework that automates, orchestrates, manages, and tracks all the processes between each handoff within the assembly line of software development, creating an automated software factory.");
@ -86,12 +86,12 @@ public class ParseImagesFromJsonTest {
image2.setArchitecture("i386");
image2.setPlatform("Redhat Enterprise Linux (32-bit)/5.4");
image2.setCreatedTime(new Date(1265647398869l));
image2.setLocation(1);
image2.setLocation("1");
image2.setSupportedInstanceTypes(ImmutableSet.of("LARGE", "MEDIUM"));
// image.setProductCodes();
image2
.setDocumentation("https://www-180.ibm.com/cloud/enterprise/beta/ram.ws/RAMSecure/artifact/{28C7B870-2C0A-003F-F886-B89F5B413B77}/1.0/GettingStarted.html");
image2.setId(10005598);
image2.setId("10005598");
image2
.setDescription("Rational Requirements Composer helps teams define and use requirements effectively across the project lifecycle.");

View File

@ -59,9 +59,9 @@ public class ParseInstanceFromJsonTest {
public void test() {
Instance instance = new Instance(new Date(1260472231726l), ImmutableSet.of(new Software(
"10 SP2", "OS", "SUSE Linux Enterprise")), "129.33.197.78", 7430l, "DEFAULT", "ABC",
"MEDIUM", 5, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", 1, 3l, ImmutableSet
.<String> of(), "ABC", 7430l, new Date(1263064240837l));
"10 SP2", "OS", "SUSE Linux Enterprise")), "129.33.197.78", "7430", "DEFAULT", "ABC",
"MEDIUM", 5, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", "1", "3", ImmutableSet
.<String> of(), "ABC", "7430", new Date(1263064240837l));
Instance compare = handler.apply(new HttpResponse(ParseInstanceFromJsonTest.class
.getResourceAsStream("/instance.json")));

View File

@ -58,17 +58,17 @@ public class ParseInstancesFromJsonTest {
public void test() {
Instance instance1 = new Instance(new Date(1260472231726l), ImmutableSet.of(new Software(
"10 SP2", "OS", "SUSE Linux Enterprise")), "129.33.197.78", 7430l, "DEFAULT", "ABC",
"MEDIUM", 5, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", 1, 3l, ImmutableSet
.<String> of(), "ABC", 7430l, new Date(1263064240837l));
"10 SP2", "OS", "SUSE Linux Enterprise")), "129.33.197.78", "7430", "DEFAULT",
"ABC", "MEDIUM", 5, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", "1", "3",
ImmutableSet.<String> of(), "ABC", "7430", new Date(1263064240837l));
Instance instance2 = new Instance(new Date(1260472231727l), ImmutableSet.of(new Software(
"10 SP3", "OS", "SUSE Linux Enterprise")), "129.33.197.79", 7431l, "DEFAULT", "ABC",
"MEDIUM", 6, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", 2, 4l, ImmutableSet
.<String> of(), "ABC", 7431l, new Date(1263064240838l));
Set<? extends Instance> compare = handler.apply(new HttpResponse(ParseInstancesFromJsonTest.class
.getResourceAsStream("/instances.json")));
"10 SP3", "OS", "SUSE Linux Enterprise")), "129.33.197.79", "7431", "DEFAULT",
"ABC", "MEDIUM", 6, "aadelucc@us.ibm.com", "vm723.developer.ihost.com", "2", "4",
ImmutableSet.<String> of(), "ABC", "7431", new Date(1263064240838l));
Set<? extends Instance> compare = handler.apply(new HttpResponse(
ParseInstancesFromJsonTest.class.getResourceAsStream("/instances.json")));
assert (compare.contains(instance1));
assert (compare.contains(instance2));
}

View File

@ -57,7 +57,7 @@ public class ParseKeyFromJsonTest {
}
public void test() {
Key key = new Key(true, ImmutableSet.<Long> of(1l),
Key key = new Key(true, ImmutableSet.<String> of("1"),
"AAAB3NzaC1yc2EAAAADAQABAAABAQCqBw7a+...", "DEFAULT", new Date(1260428507510l));
Key compare = handler.apply(new HttpResponse(ParseKeyFromJsonTest.class

View File

@ -56,9 +56,9 @@ public class ParseKeysFromJsonTest {
}
public void test() {
Key key1 = new Key(true, ImmutableSet.<Long> of(1l),
Key key1 = new Key(true, ImmutableSet.<String> of("1"),
"AAAB3NzaC1yc2EAAAADAQABAAABAQCqBw7a+...", "DEFAULT", new Date(1260428507510l));
Key key2 = new Key(false, ImmutableSet.<Long> of(), "AAAB3NzaC1yc2EAAAADAQABAAABAQCqBw7a+",
Key key2 = new Key(false, ImmutableSet.<String> of(), "AAAB3NzaC1yc2EAAAADAQABAAABAQCqBw7a+",
"BEAR", new Date(1260428507511l));
Set<? extends Key> compare = handler.apply(new HttpResponse(ParseKeysFromJsonTest.class

View File

@ -58,8 +58,8 @@ public class ParseVolumeFromJsonTest {
public void test() {
Volume volume = new Volume(2l, 5, 50, "aadelucc@us.ibm.com", new Date(1260469075119l), 1,
ImmutableSet.<String> of(), "ext3", "New Storage", 67l);
Volume volume = new Volume("2", 5, 50, "aadelucc@us.ibm.com", new Date(1260469075119l), "1",
ImmutableSet.<String> of(), "ext3", "New Storage", "67");
Volume compare = handler.apply(new HttpResponse(ParseVolumeFromJsonTest.class
.getResourceAsStream("/volume.json")));

View File

@ -56,11 +56,11 @@ public class ParseVolumesFromJsonTest {
}
public void test() {
Volume volume1 = new Volume(2l, 5, 50, "aadelucc@us.ibm.com", new Date(1260469075119l), 1,
ImmutableSet.<String> of(), "ext3", "New Storage", 67l);
Volume volume1 = new Volume("2", 5, 50, "aadelucc@us.ibm.com", new Date(1260469075119l), "1",
ImmutableSet.<String> of(), "ext3", "New Storage", "67");
Volume volume2 = new Volume(null, 6, 51, "aadelucc@us.ibm.com", new Date(1260469075120l), 2,
ImmutableSet.<String> of("abrad"), "ext3", "New Storage1", 68l);
Volume volume2 = new Volume(null, 6, 51, "aadelucc@us.ibm.com", new Date(1260469075120l),
"2", ImmutableSet.<String> of("abrad"), "ext3", "New Storage1", "68");
Set<? extends Volume> compare = handler.apply(new HttpResponse(ParseVolumesFromJsonTest.class
.getResourceAsStream("/volumes.json")));

View File

@ -53,7 +53,7 @@ public class LocationHandlerTest extends BaseHandlerTest {
.<String, String> of(
));
Location expects = new Location(1, "US North East: Poughkeepsie, NY", null, "POK",
Location expects = new Location("1", "US North East: Poughkeepsie, NY", null, "POK",
capabilites);
assertEquals(result, expects);
}

View File

@ -55,7 +55,7 @@ public class LocationsHandlerTest extends BaseHandlerTest {
.<String, String> of(
));
Location location1 = new Location(1, "US North East: Poughkeepsie, NY", null, "POK",
Location location1 = new Location("1", "US North East: Poughkeepsie, NY", null, "POK",
capabilites);
assertEquals(result, ImmutableSet.of(location1));
@ -79,7 +79,7 @@ public class LocationsHandlerTest extends BaseHandlerTest {
.<String, String> of(
));
Location location1 = new Location(1, "US North East: Poughkeepsie, NY", null, "POK",
Location location1 = new Location("1", "US North East: Poughkeepsie, NY", null, "POK",
capabilites);
capabilites = ImmutableMap.<String, Map<String, String>> of(
@ -92,7 +92,7 @@ public class LocationsHandlerTest extends BaseHandlerTest {
.<String, String> of(
));
Location location2 = new Location(1, "US North East: Poughkeepsie, NY", null, "POK",
Location location2 = new Location("1", "US North East: Poughkeepsie, NY", null, "POK",
capabilites);
assertEquals(result, ImmutableSet.of(location1, location2));