Issue 419: cloudsigma server lifecycle now works

This commit is contained in:
Adrian Cole 2010-12-19 16:33:52 +01:00
parent 70fbb3a5b8
commit bd7d9fb594
31 changed files with 1416 additions and 64 deletions

View File

@ -28,19 +28,28 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.cloudsigma.binders.BindCloneDriveOptionsToPlainTextString;
import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.elasticstack.CommonElasticStackAsyncClient; import org.jclouds.elasticstack.CommonElasticStackAsyncClient;
import org.jclouds.elasticstack.ElasticStackClient; import org.jclouds.elasticstack.ElasticStackClient;
import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString; import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString;
import org.jclouds.elasticstack.binders.BindDriveToPlainTextString; import org.jclouds.elasticstack.binders.BindDriveToPlainTextString;
import org.jclouds.elasticstack.binders.BindServerToPlainTextString;
import org.jclouds.elasticstack.domain.Drive; import org.jclouds.elasticstack.domain.Drive;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.elasticstack.functions.SplitNewlines;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapPayloadParam;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -84,7 +93,17 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient {
ListenableFuture<Set<String>> listStandardImages(); ListenableFuture<Set<String>> listStandardImages();
/** /**
* @see ElasticStackClient#listDriveInfo() * @see CloudSigmaClient#cloneDrive
*/
@POST
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/{uuid}/clone")
@MapBinder(BindCloneDriveOptionsToPlainTextString.class)
ListenableFuture<? extends DriveInfo> cloneDrive(@PathParam("uuid") String sourceUuid,
@MapPayloadParam("name") String newName, CloneDriveOptions... options);
/**
* {@inheritDoc}
*/ */
@Override @Override
@GET @GET
@ -93,7 +112,7 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient {
ListenableFuture<Set<? extends org.jclouds.elasticstack.domain.DriveInfo>> listDriveInfo(); ListenableFuture<Set<? extends org.jclouds.elasticstack.domain.DriveInfo>> listDriveInfo();
/** /**
* @see ElasticStackClient#getDriveInfo * {@inheritDoc}
*/ */
@Override @Override
@GET @GET
@ -103,7 +122,7 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient {
ListenableFuture<? extends DriveInfo> getDriveInfo(@PathParam("uuid") String uuid); ListenableFuture<? extends DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
/** /**
* @see ElasticStackClient#createDrive * {@inheritDoc}
*/ */
@Override @Override
@POST @POST
@ -113,12 +132,53 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient {
ListenableFuture<? extends DriveInfo> createDrive(@BinderParam(BindDriveToPlainTextString.class) Drive createDrive); ListenableFuture<? extends DriveInfo> createDrive(@BinderParam(BindDriveToPlainTextString.class) Drive createDrive);
/** /**
* @see ElasticStackClient#setDriveData * {@inheritDoc}
*/ */
@Override
@POST @POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class) @ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
@Path("/drives/{uuid}/set") @Path("/drives/{uuid}/set")
ListenableFuture<? extends DriveInfo> setDriveData(@PathParam("uuid") String uuid, ListenableFuture<? extends DriveInfo> setDriveData(@PathParam("uuid") String uuid,
@BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive); @BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive);
/**
* {@inheritDoc}
*/
@Override
@POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/create")
ListenableFuture<? extends ServerInfo> createServer(
@BinderParam(BindServerToPlainTextString.class) Server createServer);
/**
* {@inheritDoc}
*/
@Override
@GET
@Path("/servers/info")
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class)
ListenableFuture<Set<? extends ServerInfo>> listServerInfo();
/**
* {@inheritDoc}
*/
@Override
@GET
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/{uuid}/info")
ListenableFuture<? extends ServerInfo> getServerInfo(@PathParam("uuid") String uuid);
/**
* {@inheritDoc}
*/
@Override
@POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/{uuid}/set")
ListenableFuture<? extends ServerInfo> setServerConfiguration(@PathParam("uuid") String uuid,
@BinderParam(BindServerToPlainTextString.class) Server setServer);
} }

View File

@ -23,6 +23,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.elasticstack.CommonElasticStackClient; import org.jclouds.elasticstack.CommonElasticStackClient;
import org.jclouds.elasticstack.domain.Drive; import org.jclouds.elasticstack.domain.Drive;
@ -60,6 +61,19 @@ public interface CloudSigmaClient extends CommonElasticStackClient {
*/ */
Set<String> listStandardImages(); Set<String> listStandardImages();
/**
* Clone an existing drive. By default, the size is the same as the source
*
* @param sourceUuid
* source to clone
* @param newName
* name of the resulting drive
* @param options
* options to control size
* @return new drive
*/
DriveInfo cloneDrive(String sourceUuid, String newName, CloneDriveOptions... options);
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */

View File

@ -0,0 +1,91 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.core.MediaType;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.elasticstack.functions.ListOfMapsToListOfKeyValuesDelimitedByBlankLines;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindCloneDriveOptionsToPlainTextString implements MapBinder {
private final ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines;
@Inject
public BindCloneDriveOptionsToPlainTextString(
ListOfMapsToListOfKeyValuesDelimitedByBlankLines listOfMapsToListOfKeyValuesDelimitedByBlankLines) {
this.listOfMapsToListOfKeyValuesDelimitedByBlankLines = listOfMapsToListOfKeyValuesDelimitedByBlankLines;
}
@Override
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
"this binder is only valid for GeneratedHttpRequests!");
@SuppressWarnings("unchecked")
GeneratedHttpRequest<CloudSigmaAsyncClient> gRequest = (GeneratedHttpRequest<CloudSigmaAsyncClient>) request;
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
CloneDriveOptions options = findOptionsInArgsOrNull(gRequest);
if (options != null) {
postParams = ImmutableMap.<String, String> builder().putAll(postParams).putAll(options.getOptions()).build();
}
request.setPayload(listOfMapsToListOfKeyValuesDelimitedByBlankLines.apply(ImmutableSet.of(postParams)));
request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_PLAIN);
}
static CloneDriveOptions findOptionsInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
for (Object arg : gRequest.getArgs()) {
if (arg instanceof CloneDriveOptions) {
return (CloneDriveOptions) arg;
} else if (arg instanceof CloneDriveOptions[]) {
CloneDriveOptions[] options = (CloneDriveOptions[]) arg;
return (options.length > 0) ? options[0] : null;
}
}
return null;
}
@Override
public void bindToRequest(HttpRequest request, Object input) {
throw new UnsupportedOperationException();
}
}

View File

@ -26,11 +26,13 @@ import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.CloudSigmaClient; import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap; import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap;
import org.jclouds.cloudsigma.functions.DriveDataToMap; import org.jclouds.cloudsigma.functions.DriveDataToMap;
import org.jclouds.cloudsigma.functions.ServerToMap;
import org.jclouds.elasticstack.domain.Device; import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.Drive; import org.jclouds.elasticstack.domain.Drive;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.DriveMetrics; import org.jclouds.elasticstack.domain.DriveMetrics;
import org.jclouds.elasticstack.domain.NIC; import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.ServerMetrics; import org.jclouds.elasticstack.domain.ServerMetrics;
import org.jclouds.elasticstack.functions.MapToDevices; import org.jclouds.elasticstack.functions.MapToDevices;
import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId; import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId;
@ -86,6 +88,8 @@ public class CloudSigmaRestClientModule extends RestClientModule<CloudSigmaClien
}).to(MapToServerMetrics.class); }).to(MapToServerMetrics.class);
bind(new TypeLiteral<Function<Device, String>>() { bind(new TypeLiteral<Function<Device, String>>() {
}).to(DeviceToId.class); }).to(DeviceToId.class);
bind(new TypeLiteral<Function<Server, Map<String, String>>>() {
}).to(ServerToMap.class);
} }
@Override @Override

View File

@ -29,7 +29,6 @@ import javax.inject.Singleton;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Maps;
/** /**
* *
@ -46,14 +45,6 @@ public class DriveDataToMap implements Function<DriveData, Map<String, String>>
@Override @Override
public Map<String, String> apply(DriveData from) { public Map<String, String> apply(DriveData from) {
return Maps.transformEntries(renameKey(baseDriveToMap.apply(from), "tags", "use"), return renameKey(baseDriveToMap.apply(from), "tags", "use");
new Maps.EntryTransformer<String, String, String>() {
@Override
public String transformEntry(String arg0, String arg1) {
return "use".equals(arg0) ? arg1.replace(' ', ',') : arg1;
}
});
} }
} }

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.http.HttpResponse;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class KeyValuesDelimitedByBlankLinesToServerInfo implements Function<HttpResponse, ServerInfo> {
private final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser;
@Inject
public KeyValuesDelimitedByBlankLinesToServerInfo(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser) {
this.setParser = setParser;
}
@Override
public ServerInfo apply(HttpResponse response) {
Set<ServerInfo> drives = setParser.apply(response);
if (drives.size() == 0)
return null;
return Iterables.get(drives, 0);
}
}

View File

@ -0,0 +1,62 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ReturnStringIf2xx;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet implements Function<HttpResponse, Set<ServerInfo>> {
private final ReturnStringIf2xx returnStringIf200;
private final ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter;
private final MapToServerInfo mapToServer;
@Inject
ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet(ReturnStringIf2xx returnStringIf200,
ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter, MapToServerInfo mapToServer) {
this.returnStringIf200 = returnStringIf200;
this.mapConverter = mapConverter;
this.mapToServer = mapToServer;
}
@Override
public Set<ServerInfo> apply(HttpResponse response) {
String text = returnStringIf200.apply(response);
if (text == null || text.trim().equals(""))
return ImmutableSet.<ServerInfo> of();
return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToServer));
}
}

View File

@ -50,7 +50,7 @@ public class MapToDriveInfo implements Function<Map<String, String>, DriveInfo>
return null; return null;
DriveInfo.Builder builder = DriveInfo.Builder.fromDriveInfo(mapToDriveInfo.apply(from)); DriveInfo.Builder builder = DriveInfo.Builder.fromDriveInfo(mapToDriveInfo.apply(from));
if (from.containsKey("use")) if (from.containsKey("use"))
builder.tags(Splitter.on(',').split(from.get("use"))); builder.tags(Splitter.on(' ').split(from.get("use")));
if (from.containsKey("bits")) if (from.containsKey("bits"))
builder.bits(new Integer(from.get("bits"))); builder.bits(new Integer(from.get("bits")));
if (from.containsKey("url")) if (from.containsKey("url"))

View File

@ -0,0 +1,95 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.domain.ServerMetrics;
import org.jclouds.elasticstack.domain.ServerStatus;
import org.jclouds.elasticstack.domain.VNC;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
/**
*
* @author Adrian Cole
*/
@Singleton
public class MapToServerInfo implements Function<Map<String, String>, ServerInfo> {
private final Function<Map<String, String>, Map<String, ? extends Device>> mapToDevices;
private final Function<Map<String, String>, ServerMetrics> mapToMetrics;
private final Function<Map<String, String>, List<NIC>> mapToNICs;
@Inject
public MapToServerInfo(Function<Map<String, String>, Map<String, ? extends Device>> mapToDevices,
Function<Map<String, String>, ServerMetrics> mapToMetrics, Function<Map<String, String>, List<NIC>> mapToNICs) {
this.mapToDevices = mapToDevices;
this.mapToMetrics = mapToMetrics;
this.mapToNICs = mapToNICs;
}
@Override
public ServerInfo apply(Map<String, String> from) {
if (from.size() == 0)
return null;
ServerInfo.Builder builder = new ServerInfo.Builder();
builder.name(from.get("name"));
builder.description(from.get("description"));
builder.persistent(Boolean.parseBoolean(from.get("persistent")));
if (from.containsKey("use"))
builder.tags(Splitter.on(' ').split(from.get("use")));
if (from.containsKey("status"))
builder.status(ServerStatus.fromValue(from.get("status")));
if (from.containsKey("smp") && !"auto".equals(from.get("smp")))
builder.smp(new Integer(from.get("smp")));
builder.cpu(Integer.parseInt(from.get("cpu")));
builder.mem(Integer.parseInt(from.get("mem")));
builder.user(from.get("user"));
if (from.containsKey("started"))
builder.started(new Date(new Long(from.get("started"))));
builder.uuid(from.get("server"));
builder.vnc(new VNC(from.get("vnc:ip"), from.get("vnc:password"), from.containsKey("vnc:tls")
&& Boolean.valueOf(from.get("vnc:tls"))));
if (from.containsKey("boot"))
builder.bootDeviceIds(Splitter.on(' ').split(from.get("boot")));
Map<String, String> metadata = Maps.newLinkedHashMap();
for (Entry<String, String> entry : from.entrySet()) {
if (entry.getKey().startsWith("user:"))
metadata.put(entry.getKey().substring(entry.getKey().indexOf(':') + 1), entry.getValue());
}
builder.userMetadata(metadata);
builder.nics(mapToNICs.apply(from));
builder.devices(mapToDevices.apply(from));
builder.metrics(mapToMetrics.apply(from));
return builder.build();
}
}

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Map.Entry;
import javax.inject.Singleton;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.Server;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerToMap implements Function<Server, Map<String, String>> {
@Override
public Map<String, String> apply(Server from) {
checkNotNull(from, "server");
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
builder.put("name", from.getName());
builder.put("cpu", from.getCpu() + "");
if (from.getSmp() != null)
builder.put("smp", from.getSmp() + "");
else
builder.put("smp", "auto");
builder.put("mem", from.getMem() + "");
builder.put("persistent", from.isPersistent() + "");
if (from.getBootDeviceIds().size() != 0)
builder.put("boot", Joiner.on(' ').join(from.getBootDeviceIds()));
for (Entry<String, ? extends Device> entry : from.getDevices().entrySet()) {
builder.put(entry.getKey(), entry.getValue().getDriveUuid());
builder.put(entry.getKey() + ":media", entry.getValue().getMediaType().toString());
}
int nicId = 0;
for (NIC nic : from.getNics()) {
builder.put("nic:" + nicId + ":model", nic.getModel().toString());
if (nic.getDhcp() != null)
builder.put("nic:" + nicId + ":dhcp", nic.getDhcp());
if (nic.getVlan() != null)
builder.put("nic:" + nicId + ":vlan", nic.getVlan());
if (nic.getMac() != null)
builder.put("nic:" + nicId + ":mac", nic.getMac());
nicId++;
}
builder.put("vnc:ip", from.getVnc().getIp() == null ? "auto" : from.getVnc().getIp());
if (from.getVnc().getPassword() != null)
builder.put("vnc:password", from.getVnc().getPassword());
if (from.getVnc().isTls())
builder.put("vnc:tls", "on");
if (from.getTags().size() != 0)
builder.put("use", Joiner.on(' ').join(from.getTags()));
for (Entry<String, String> entry : from.getUserMetadata().entrySet())
builder.put("user:" + entry.getKey(), entry.getValue());
return builder.build();
}
}

View File

@ -0,0 +1,72 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.options;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
* Contains options supported for clone drive operations. <h2>
* Usage</h2> The recommended way to instantiate a CloneDriveOptions object is to statically import
* CloneDriveOptions.Builder.* and invoke a static creation method followed by an instance mutator
* (if needed):
* <p/>
* <code>
* import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.*;
*
*
* Payload payload = client.cloneDrive("drive-uuid","newName", size(2*1024*1024l));
* <code>
*
* @author Adrian Cole
*
*/
public class CloneDriveOptions {
private final Map<String, String> options = Maps.newLinkedHashMap();
/**
* adjust to new size in bytes
*/
public CloneDriveOptions size(long size) {
checkArgument(size >= 0, "size must be >= 0");
options.put("size", size + "");
return this;
}
public static class Builder {
/**
* @see CloneDriveOptions#size
*/
public static CloneDriveOptions size(long size) {
CloneDriveOptions options = new CloneDriveOptions();
return options.size(size);
}
}
public Map<String, String> getOptions() {
return ImmutableMap.copyOf(options);
}
}

View File

@ -26,22 +26,31 @@ import java.lang.reflect.Method;
import java.util.Properties; import java.util.Properties;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.elasticstack.binders.BindServerToPlainTextStringTest;
import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.Drive; import org.jclouds.elasticstack.domain.Drive;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.elasticstack.functions.SplitNewlines;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec; import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
/** /**
@ -131,7 +140,8 @@ public class CloudSigmaAsyncClientTest extends RestClientTest<CloudSigmaAsyncCli
public void testCreateDrive() throws SecurityException, NoSuchMethodException, IOException { public void testCreateDrive() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("createDrive", Drive.class); Method method = CloudSigmaAsyncClient.class.getMethod("createDrive", Drive.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method,
new CreateDriveRequest.Builder().name("foo").tags(ImmutableList.of("production", "candy")).size(10000l).build()); new CreateDriveRequest.Builder().name("foo").tags(ImmutableList.of("production", "candy")).size(10000l)
.build());
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/create HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/create HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
@ -145,6 +155,41 @@ public class CloudSigmaAsyncClientTest extends RestClientTest<CloudSigmaAsyncCli
} }
public void testCloneDrive() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("cloneDrive", String.class, String.class,
CloneDriveOptions[].class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "sourceid", "newname");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/sourceid/clone HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, "name newname", "text/plain", false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToDriveInfo.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testCloneDriveOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("cloneDrive", String.class, String.class,
CloneDriveOptions[].class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "sourceid", "newname",
new CloneDriveOptions().size(1024l));
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/sourceid/clone HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, "name newname\nsize 1024", "text/plain", false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToDriveInfo.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testSetDriveData() throws SecurityException, NoSuchMethodException, IOException { public void testSetDriveData() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("setDriveData", String.class, DriveData.class); Method method = CloudSigmaAsyncClient.class.getMethod("setDriveData", String.class, DriveData.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "100", GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "100",
@ -152,16 +197,231 @@ public class CloudSigmaAsyncClientTest extends RestClientTest<CloudSigmaAsyncCli
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/100/set HTTP/1.1"); assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/100/set HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, "name foo\nsize 10000\nuse production,candy", "text/plain", false); assertPayloadEquals(httpRequest, "name foo\nsize 10000\nuse production candy", "text/plain", false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToDriveInfo.class); assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToDriveInfo.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testListServers() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("listServers");
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/servers/list HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
// now make sure request filters apply by replaying
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/servers/list HTTP/1.1");
// for example, using basic authentication, we should get "only one"
// header
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\nAuthorization: Basic Zm9vOmJhcg==\n");
assertPayloadEquals(httpRequest, null, null, false);
// TODO: insert expected response class, which probably extends ParseJson
assertResponseParserClassEquals(method, httpRequest, SplitNewlines.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testListServerInfo() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("listServerInfo");
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/servers/info HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testGetServerInfo() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("getServerInfo", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/servers/uuid/info HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToServerInfo.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest); checkFilters(httpRequest);
} }
public void testCreateServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("createServer", Server.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method,
BindServerToPlainTextStringTest.SERVER);
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/create HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, BindServerToPlainTextStringTest.CREATED_SERVER, "text/plain", false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToServerInfo.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testSetServerConfiguration() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("setServerConfiguration", String.class, Server.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "100",
BindServerToPlainTextStringTest.SERVER);
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/100/set HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, BindServerToPlainTextStringTest.CREATED_SERVER, "text/plain", false);
assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToServerInfo.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testDestroyServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("destroyServer", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/uuid/destroy HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testStartServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("startServer", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/uuid/start HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testStopServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("stopServer", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/uuid/stop HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testShutdownServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("shutdownServer", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/uuid/shutdown HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testResetServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("resetServer", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/servers/uuid/reset HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(httpRequest);
}
public void testListDrives() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("listDrives");
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/drives/list HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
// now make sure request filters apply by replaying
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, "GET https://api.cloudsigma.com/drives/list HTTP/1.1");
// for example, using basic authentication, we should get "only one"
// header
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\nAuthorization: Basic Zm9vOmJhcg==\n");
assertPayloadEquals(httpRequest, null, null, false);
// TODO: insert expected response class, which probably extends ParseJson
assertResponseParserClassEquals(method, httpRequest, SplitNewlines.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
}
public void testDestroyDrive() throws SecurityException, NoSuchMethodException, IOException {
Method method = CloudSigmaAsyncClient.class.getMethod("destroyDrive", String.class);
GeneratedHttpRequest<CloudSigmaAsyncClient> httpRequest = processor.createRequest(method, "uuid");
assertRequestLineEquals(httpRequest, "POST https://api.cloudsigma.com/drives/uuid/destroy HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnVoidOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override @Override
protected void checkFilters(HttpRequest request) { protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1); assertEquals(request.getFilters().size(), 1);

View File

@ -26,9 +26,14 @@ import java.util.Set;
import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.DriveInfo;
import org.jclouds.cloudsigma.domain.DriveType; import org.jclouds.cloudsigma.domain.DriveType;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.elasticstack.CommonElasticStackClientLiveTest; import org.jclouds.elasticstack.CommonElasticStackClientLiveTest;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/** /**
* Tests behavior of {@code CloudSigmaClient} * Tests behavior of {@code CloudSigmaClient}
* *
@ -39,6 +44,8 @@ public class CloudSigmaClientLiveTest extends CommonElasticStackClientLiveTest<C
public CloudSigmaClientLiveTest() { public CloudSigmaClientLiveTest() {
provider = "cloudsigma"; provider = "cloudsigma";
driveSize = 8 * 1024 * 1024 * 1024l;
maxDriveImageTime = 300;
} }
@Test @Test
@ -58,6 +65,7 @@ public class CloudSigmaClientLiveTest extends CommonElasticStackClientLiveTest<C
Set<String> drives = client.listStandardImages(); Set<String> drives = client.listStandardImages();
assertNotNull(drives); assertNotNull(drives);
} }
@Override @Override
protected void checkDriveMatchesGet(org.jclouds.elasticstack.domain.DriveInfo newInfo) { protected void checkDriveMatchesGet(org.jclouds.elasticstack.domain.DriveInfo newInfo) {
super.checkDriveMatchesGet(newInfo); super.checkDriveMatchesGet(newInfo);
@ -72,7 +80,17 @@ public class CloudSigmaClientLiveTest extends CommonElasticStackClientLiveTest<C
@Override @Override
protected void prepareDrive() { protected void prepareDrive() {
// TODO Auto-generated method stub client.destroyDrive(drive.getUuid());
drive = client.cloneDrive("0b060e09-d98b-44cc-95a4-7e3a22ba1b53", drive.getName(),
new CloneDriveOptions().size(driveSize));
assert driveNotClaimed.apply(drive) : client.getDriveInfo(drive.getUuid());
System.err.println("after prepare" + client.getDriveInfo(drive.getUuid()));
}
@Override
protected void checkTagsAndMetadata(ServerInfo server2) {
// bug where tags aren't updated
assertEquals(server2.getTags(), ImmutableSet.<String> of());
assertEquals(server2.getUserMetadata(), ImmutableMap.<String, String> of());
} }
} }

View File

@ -0,0 +1,78 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.binders;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.io.IOException;
import org.jclouds.cloudsigma.options.CloneDriveOptions;
import org.jclouds.io.MutableContentMetadata;
import org.jclouds.io.Payload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class BindCloneDriveOptionsToPlainTextStringTest {
private static final BindCloneDriveOptionsToPlainTextString binder = Guice.createInjector().getInstance(
BindCloneDriveOptionsToPlainTextString.class);
public void testDefault() throws IOException {
assertInputAndArgsCreatesPayload(ImmutableMap.of("name", "newdrive"), new Object[] {}, "name newdrive");
}
public void testWithSize() throws IOException {
assertInputAndArgsCreatesPayload(ImmutableMap.of("name", "newdrive"),
new Object[] { new CloneDriveOptions().size(1024) }, "name newdrive\nsize 1024");
}
protected void assertInputAndArgsCreatesPayload(ImmutableMap<String, String> inputMap, Object[] args, String expected) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(args).atLeastOnce();
request.setPayload(expected);
Payload payload = createMock(Payload.class);
expect(request.getPayload()).andReturn(payload);
MutableContentMetadata md = createMock(MutableContentMetadata.class);
expect(payload.getContentMetadata()).andReturn(md);
md.setContentType("text/plain");
replay(request);
replay(payload);
replay(md);
binder.bindToRequest(request, inputMap);
verify(request);
verify(payload);
verify(md);
}
}

View File

@ -45,6 +45,6 @@ public class KeyValuesDelimitedByBlankLinesToDriveInfoTest {
public void testOne() { public void testOne() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class
.getResourceAsStream("/drive.txt")))), MapToDriveInfoTest.ONE); .getResourceAsStream("/cloudsigma/drive.txt")))), MapToDriveInfoTest.ONE);
} }
} }

View File

@ -0,0 +1,85 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import static org.testng.Assert.assertEquals;
import java.util.List;
import java.util.Map;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.DriveMetrics;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.ServerMetrics;
import org.jclouds.elasticstack.functions.MapToDevices;
import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId;
import org.jclouds.elasticstack.functions.MapToDriveMetrics;
import org.jclouds.elasticstack.functions.MapToNICs;
import org.jclouds.elasticstack.functions.MapToServerMetrics;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class KeyValuesDelimitedByBlankLinesToServerInfoTest {
private static final KeyValuesDelimitedByBlankLinesToServerInfo FN = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bind(new TypeLiteral<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Map<String, ? extends Device>>>() {
}).to(MapToDevices.class);
bind(new TypeLiteral<Function<Map<String, String>, Map<String, ? extends DriveMetrics>>>() {
}).to(MapToDriveMetrics.class);
bind(new TypeLiteral<Function<Map<String, String>, ServerMetrics>>() {
}).to(MapToServerMetrics.class);
bind(new TypeLiteral<Function<Device, String>>() {
}).to(DeviceToId.class);
}
}).getInstance(KeyValuesDelimitedByBlankLinesToServerInfo.class);
public void testNone() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), null);
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), null);
assertEquals(FN.apply(new HttpResponse(200, "", null)), null);
}
public void testOne() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class
.getResourceAsStream("/servers.txt")))), MapToServerInfoTest.ONE);
}
public void testNew() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class
.getResourceAsStream("/new_server.txt")))), MapToServerInfoTest.NEW);
}
}

View File

@ -47,6 +47,6 @@ public class ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest {
public void testOne() { public void testOne() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class
.getResourceAsStream("/drive.txt")))), ImmutableSet.<DriveInfo> of(MapToDriveInfoTest.ONE)); .getResourceAsStream("/cloudsigma/drive.txt")))), ImmutableSet.<DriveInfo> of(MapToDriveInfoTest.ONE));
} }
} }

View File

@ -0,0 +1,85 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import static org.testng.Assert.assertEquals;
import java.util.List;
import java.util.Map;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.DriveMetrics;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.domain.ServerMetrics;
import org.jclouds.elasticstack.functions.MapToDevices;
import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId;
import org.jclouds.elasticstack.functions.MapToDriveMetrics;
import org.jclouds.elasticstack.functions.MapToNICs;
import org.jclouds.elasticstack.functions.MapToServerMetrics;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest {
private static final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet FN = Guice.createInjector(
new AbstractModule() {
@Override
protected void configure() {
bind(new TypeLiteral<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Map<String, ? extends Device>>>() {
}).to(MapToDevices.class);
bind(new TypeLiteral<Function<Map<String, String>, Map<String, ? extends DriveMetrics>>>() {
}).to(MapToDriveMetrics.class);
bind(new TypeLiteral<Function<Map<String, String>, ServerMetrics>>() {
}).to(MapToServerMetrics.class);
bind(new TypeLiteral<Function<Device, String>>() {
}).to(DeviceToId.class);
}
}).getInstance(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class);
public void testNone() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), ImmutableSet.<ServerInfo> of());
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))),
ImmutableSet.<ServerInfo> of());
assertEquals(FN.apply(new HttpResponse(200, "", null)), ImmutableSet.<ServerInfo> of());
}
public void testOne() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class
.getResourceAsStream("/servers.txt")))), ImmutableSet.<ServerInfo> of(MapToServerInfoTest.ONE,
MapToServerInfoTest.TWO));
}
}

View File

@ -90,7 +90,7 @@ public class MapToDriveInfoTest {
public void testComplete() throws IOException { public void testComplete() throws IOException {
Map<String, String> input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply( Map<String, String> input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply(
Utils.toStringAndClose(MapToDriveInfoTest.class.getResourceAsStream("/drive.txt"))).get(0); Utils.toStringAndClose(MapToDriveInfoTest.class.getResourceAsStream("/cloudsigma/drive.txt"))).get(0);
assertEquals(MAP_TO_DRIVE.apply(input), ONE); assertEquals(MAP_TO_DRIVE.apply(input), ONE);

View File

@ -0,0 +1,167 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Date;
import java.util.Map;
import org.jclouds.elasticstack.domain.DriveMetrics;
import org.jclouds.elasticstack.domain.IDEDevice;
import org.jclouds.elasticstack.domain.MediaType;
import org.jclouds.elasticstack.domain.Model;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.domain.ServerMetrics;
import org.jclouds.elasticstack.domain.ServerStatus;
import org.jclouds.elasticstack.domain.VNC;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToListOfMaps;
import org.jclouds.elasticstack.functions.MapToDevices;
import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId;
import org.jclouds.elasticstack.functions.MapToDriveMetrics;
import org.jclouds.elasticstack.functions.MapToNICs;
import org.jclouds.elasticstack.functions.MapToServerMetrics;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class MapToServerInfoTest {
public static ServerInfo ONE = new ServerInfo.Builder()
.persistent(true)
.uuid("f8bee9cd-8e4b-4a05-8593-1314e3bfe49b")
.cpu(2000)
.bootDeviceIds(ImmutableSet.of("ide:0:0"))
.smp(1)
.mem(1024)
.status(ServerStatus.ACTIVE)
.started(new Date(1291493868l))
.user("2f6244eb-50bc-4403-847e-f03cc3706a1f")
.name("jo")
.vnc(new VNC("46.20.114.124", "HfHzVmLT", false))
.nics(ImmutableSet.of(new NIC.Builder()
.model(Model.E1000)
.dhcp("46.20.114.124")
.block(
ImmutableList.of("tcp/43594", "tcp/5902", "udp/5060", "tcp/5900", "tcp/5901", "tcp/21", "tcp/22",
"tcp/23", "tcp/25", "tcp/110", "tcp/143", "tcp/43595")).build()))
.devices(
ImmutableMap.of("ide:0:0",
new IDEDevice.Builder((int) 0, (int) 0).uuid("4af85ed3-0caa-4736-8a26-a33d7de0a122").build()
))
.metrics(
new ServerMetrics.Builder()
.tx(2550)
.txPackets(31)
.rx(455530)
.rxPackets(7583)
.driveMetrics(
ImmutableMap.of("ide:0:0", new DriveMetrics.Builder().readRequests(11154)
.readBytes(45686784).writeRequests(3698).writeBytes(15147008).build())).build())
.build();
public static ServerInfo TWO = new ServerInfo.Builder()
.status(ServerStatus.STOPPED)
.name("Demo")
.mem(1024)
.cpu(2000)
.persistent(true)
.uuid("0f962616-2071-4173-be79-7dd084271edf")
.bootDeviceIds(ImmutableSet.of("ide:0:0"))
.user("2f6244eb-50bc-4403-847e-f03cc3706a1f")
.vnc(new VNC("auto", "HWbjvrg2", false))
.nics(ImmutableSet.of(new NIC.Builder().model(Model.E1000).dhcp("auto").build()))
.devices(
ImmutableMap.of(
"ide:0:0",
new IDEDevice.Builder((int) 0, (int) 0).uuid("853bb98a-4fff-4c2f-a265-97c363f19ea5")
.mediaType(MediaType.CDROM).build()))
.metrics(
new ServerMetrics.Builder().driveMetrics(ImmutableMap.of("ide:0:0", new DriveMetrics.Builder().build()))
.build()).build();
private static final MapToServerInfo MAP_TO_DRIVE = new MapToServerInfo(new MapToDevices(new DeviceToId()),
new MapToServerMetrics(new MapToDriveMetrics()), new MapToNICs());
public void testEmptyMapReturnsNull() {
assertEquals(MAP_TO_DRIVE.apply(ImmutableMap.<String, String> of()), null);
}
public void testBasics() {
ServerInfo expects = new ServerInfo.Builder().name("foo").uuid("hello").vnc(new VNC("auto", null, false))
.cpu(1000).mem(2048).metrics(new ServerMetrics.Builder().build()).build();
assertEquals(MAP_TO_DRIVE.apply(ImmutableMap.of("name", "foo", "server", "hello", "vnc:ip", "auto", "cpu",
"1000", "mem", "2048")), expects);
}
public void testComplete() throws IOException {
Map<String, String> input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply(
Utils.toStringAndClose(MapToServerInfoTest.class.getResourceAsStream("/servers.txt"))).get(0);
assertEquals(MAP_TO_DRIVE.apply(input), ONE);
}
public static ServerInfo NEW = new ServerInfo.Builder()
.persistent(true)
.uuid("bd98615a-6f74-4d63-ad1e-b13338b9356a")
.cpu(1000)
.bootDeviceIds(ImmutableSet.of("ide:0:0"))
.smp(1)
.mem(512)
.status(ServerStatus.ACTIVE)
.started(new Date(1292695612))
.user("2f6244eb-50bc-4403-847e-f03cc3706a1f")
.name("adriancole.test")
.vnc(new VNC("83.222.249.221", "XXXXXXXX", false))
.nics(ImmutableSet.of(new NIC.Builder()
.model(Model.E1000)
.block(
ImmutableList.of("tcp/43594", "tcp/5902", "udp/5060", "tcp/5900", "tcp/5901", "tcp/21", "tcp/22",
"tcp/23", "tcp/25", "tcp/110", "tcp/143", "tcp/43595")).build()))
.devices(
ImmutableMap.of("ide:0:0",
new IDEDevice.Builder((int) 0, (int) 0).uuid("403c9a86-0aab-4e47-aa95-e9768021c4c1").build()
))
.metrics(
new ServerMetrics.Builder().driveMetrics(ImmutableMap.of("ide:0:0", new DriveMetrics.Builder().build()))
.build()).build();
public void testNew() throws IOException {
Map<String, String> input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply(
Utils.toStringAndClose(MapToServerInfoTest.class.getResourceAsStream("/new_server.txt"))).get(0);
assertEquals(MAP_TO_DRIVE.apply(input), NEW);
}
}

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.functions;
import static org.testng.Assert.assertEquals;
import org.jclouds.elasticstack.domain.IDEDevice;
import org.jclouds.elasticstack.domain.Model;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.VNC;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class ServerToMapTest {
private static final ServerToMap SERVER_TO_MAP = new ServerToMap();
public void testBasics() {
assertEquals(
SERVER_TO_MAP.apply(new Server.Builder()
.name("TestServer")
.cpu(2000)
.mem(1024)
.devices(
ImmutableMap.of("ide:0:0",
new IDEDevice.Builder(0, 0).uuid("08c92dd5-70a0-4f51-83d2-835919d254df").build()))
.bootDeviceIds(ImmutableSet.of("ide:0:0")).nics(ImmutableSet.of(new NIC.Builder().model(Model.E1000).
build())).vnc(new VNC(null, "XXXXXXXX", false)).build()),
ImmutableMap
.builder()
.putAll(ImmutableMap.of("name", "TestServer", "cpu", "2000", "smp", "auto", "mem", "1024"))
.putAll(
ImmutableMap.of("persistent", "false", "boot", "ide:0:0", "ide:0:0",
"08c92dd5-70a0-4f51-83d2-835919d254df"))
.putAll(
ImmutableMap.of("ide:0:0:media", "disk", "nic:0:model", "e1000", "vnc:ip", "auto",
"vnc:password", "XXXXXXXX")).build());
}
}

View File

@ -0,0 +1,59 @@
/**
*
* Copyright (C) 2010 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.cloudsigma.options;
import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.size;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.testng.annotations.Test;
/**
* Tests possible uses of CloneDriveOptions and CloneDriveOptions.Builder.*
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class CloneDriveOptionsTest {
@Test
public void testNullSize() {
CloneDriveOptions options = new CloneDriveOptions();
assertNull(options.getOptions().get("size"));
}
@Test
public void testSize() {
CloneDriveOptions options = new CloneDriveOptions().size(1024);
assertEquals(options.getOptions().get("size"), "1024");
}
@Test
public void testSizeStatic() {
CloneDriveOptions options = size(1024);
assertEquals(options.getOptions().get("size"), "1024");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testSizeNegative() {
size(-1);
}
}

View File

@ -1,5 +1,5 @@
status active status active
use networking,security,gateway use networking security gateway
name Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System name Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System
bits 64 bits 64
url http://www.ubuntu.com url http://www.ubuntu.com

View File

@ -88,16 +88,6 @@ public interface CommonElasticStackAsyncClient {
@Path("/servers/{uuid}/info") @Path("/servers/{uuid}/info")
ListenableFuture<? extends ServerInfo> getServerInfo(@PathParam("uuid") String uuid); ListenableFuture<? extends ServerInfo> getServerInfo(@PathParam("uuid") String uuid);
/**
* @see ElasticStackClient#createAndStartServer
*/
@POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/create")
ListenableFuture<? extends ServerInfo> createAndStartServer(
@BinderParam(BindServerToPlainTextString.class) Server createServer);
/** /**
* @see ElasticStackClient#createServer * @see ElasticStackClient#createServer
*/ */
@ -109,7 +99,7 @@ public interface CommonElasticStackAsyncClient {
@BinderParam(BindServerToPlainTextString.class) Server createServer); @BinderParam(BindServerToPlainTextString.class) Server createServer);
/** /**
* @see ElasticStackClient#setServer * @see ElasticStackClient#setServerConfiguration
*/ */
@POST @POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)

View File

@ -68,14 +68,6 @@ public interface CommonElasticStackClient {
*/ */
ServerInfo createServer(Server server); ServerInfo createServer(Server server);
/**
* create and start a new server
*
* @param server
* @return newly created server
*/
ServerInfo createAndStartServer(Server server);
/** /**
* set server configuration * set server configuration
* *

View File

@ -26,10 +26,15 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.elasticstack.binders.BindServerToPlainTextString;
import org.jclouds.elasticstack.domain.ImageConversionType; import org.jclouds.elasticstack.domain.ImageConversionType;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.elasticstack.functions.ReturnPayload; import org.jclouds.elasticstack.functions.ReturnPayload;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.ResponseParser;
@ -50,6 +55,16 @@ import com.google.common.util.concurrent.ListenableFuture;
@Consumes(MediaType.TEXT_PLAIN) @Consumes(MediaType.TEXT_PLAIN)
public interface ElasticStackAsyncClient extends CommonElasticStackAsyncClient { public interface ElasticStackAsyncClient extends CommonElasticStackAsyncClient {
/**
* @see ElasticStackClient#createAndStartServer
*/
@POST
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/create")
ListenableFuture<? extends ServerInfo> createAndStartServer(
@BinderParam(BindServerToPlainTextString.class) Server createServer);
/** /**
* @see ElasticStackClient#imageDrive(String,String) * @see ElasticStackClient#imageDrive(String,String)
*/ */

View File

@ -23,6 +23,8 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.elasticstack.domain.ImageConversionType; import org.jclouds.elasticstack.domain.ImageConversionType;
import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
/** /**
@ -36,6 +38,14 @@ import org.jclouds.io.Payload;
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface ElasticStackClient extends CommonElasticStackClient { public interface ElasticStackClient extends CommonElasticStackClient {
/**
* create and start a new server
*
* @param server
* @return newly created server
*/
ServerInfo createAndStartServer(Server server);
/** /**
* Image a drive from another drive. The actual imaging process is asynchronous, with progress * Image a drive from another drive. The actual imaging process is asynchronous, with progress
* reported via drive info. * reported via drive info.

View File

@ -83,8 +83,6 @@ public class ElasticStackRestClientModule extends RestClientModule<ElasticStackC
}).to(DeviceToId.class); }).to(DeviceToId.class);
bind(new TypeLiteral<Function<Server, Map<String, String>>>() { bind(new TypeLiteral<Function<Server, Map<String, String>>>() {
}).to(ServerToMap.class); }).to(ServerToMap.class);
bind(new TypeLiteral<Function<Server, Map<String, String>>>() {
}).to(ServerToMap.class);
} }
@Override @Override

View File

@ -37,6 +37,7 @@ public class NIC {
private Model model; private Model model;
private String vlan; private String vlan;
private String mac; private String mac;
// TODO elasticstack specific
private Set<String> block = ImmutableSet.of(); private Set<String> block = ImmutableSet.of();
public Builder dhcp(String dhcp) { public Builder dhcp(String dhcp) {

View File

@ -46,7 +46,7 @@ public class Server extends Item {
protected Set<String> bootDeviceIds = ImmutableSet.of(); protected Set<String> bootDeviceIds = ImmutableSet.of();
protected List<NIC> nics = ImmutableList.of(); protected List<NIC> nics = ImmutableList.of();
protected VNC vnc; protected VNC vnc;
// TODO undocumented // TODO cloudsigma specific
protected String description; protected String description;
public Builder cpu(int cpu) { public Builder cpu(int cpu) {

View File

@ -36,7 +36,6 @@ import org.jclouds.elasticstack.domain.DriveInfo;
import org.jclouds.elasticstack.domain.DriveStatus; import org.jclouds.elasticstack.domain.DriveStatus;
import org.jclouds.elasticstack.domain.IDEDevice; import org.jclouds.elasticstack.domain.IDEDevice;
import org.jclouds.elasticstack.domain.Model; import org.jclouds.elasticstack.domain.Model;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.domain.Server; import org.jclouds.elasticstack.domain.Server;
import org.jclouds.elasticstack.domain.ServerInfo; import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.domain.ServerStatus; import org.jclouds.elasticstack.domain.ServerStatus;
@ -54,7 +53,6 @@ import org.testng.annotations.Test;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -68,7 +66,9 @@ import com.google.inject.Module;
@Test(groups = "live", sequential = true) @Test(groups = "live", sequential = true)
public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticStackClient, A extends CommonElasticStackAsyncClient> { public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticStackClient, A extends CommonElasticStackAsyncClient> {
protected static final String VNC_PASSWORD = "XXXXXXXX"; protected long driveSize = 1 * 1024 * 1024 * 1024l;
protected int maxDriveImageTime = 120;
protected String vncPassword = "Il0veVNC";
protected S client; protected S client;
protected RestContext<S, A> context; protected RestContext<S, A> context;
protected Predicate<IPSocket> socketTester; protected Predicate<IPSocket> socketTester;
@ -109,9 +109,10 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
overrides); overrides);
client = context.getApi(); client = context.getApi();
driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), 120, 1, driveNotClaimed = new RetryablePredicate<DriveInfo>(Predicates.not(new DriveClaimed(client)), maxDriveImageTime,
1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), maxDriveImageTime, 1,
TimeUnit.SECONDS); TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 120, 1, TimeUnit.SECONDS);
} }
@Test @Test
@ -159,7 +160,7 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
@Test @Test
public void testCreateDrive() throws Exception { public void testCreateDrive() throws Exception {
drive = client.createDrive(new CreateDriveRequest.Builder().name(prefix).size(1 * 1024 * 1024 * 1024l).build()); drive = client.createDrive(new CreateDriveRequest.Builder().name(prefix).size(driveSize).build());
checkCreatedDrive(); checkCreatedDrive();
DriveInfo newInfo = client.getDriveInfo(drive.getUuid()); DriveInfo newInfo = client.getDriveInfo(drive.getUuid());
@ -175,7 +176,7 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
assertNotNull(drive.getUuid()); assertNotNull(drive.getUuid());
assertNotNull(drive.getUser()); assertNotNull(drive.getUser());
assertEquals(drive.getName(), prefix); assertEquals(drive.getName(), prefix);
assertEquals(drive.getSize(), 1 * 1024 * 1024 * 1024l); assertEquals(drive.getSize(), driveSize);
assertEquals(drive.getStatus(), DriveStatus.ACTIVE); assertEquals(drive.getStatus(), DriveStatus.ACTIVE);
// for some reason, these occasionally return as 4096,1 // for some reason, these occasionally return as 4096,1
// assertEquals(info.getReadBytes(), 0l); // assertEquals(info.getReadBytes(), 0l);
@ -213,11 +214,13 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
Logger.getAnonymousLogger().info("preparing drive"); Logger.getAnonymousLogger().info("preparing drive");
prepareDrive(); prepareDrive();
Server serverRequest = Servers.small(prefix, drive.getUuid(), VNC_PASSWORD).build(); Server serverRequest = Servers.small(prefix, drive.getUuid(), vncPassword).build();
Logger.getAnonymousLogger().info("starting server"); Logger.getAnonymousLogger().info("starting server");
server = client.createAndStartServer(serverRequest); server = client.createServer(serverRequest);
checkCreatedServer(); client.startServer(server.getUuid());
server = client.getServerInfo(server.getUuid());
checkStartedServer();
Server newInfo = client.getServerInfo(server.getUuid()); Server newInfo = client.getServerInfo(server.getUuid());
checkServerMatchesGet(newInfo); checkServerMatchesGet(newInfo);
@ -228,7 +231,7 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
assertEquals(newInfo.getUuid(), server.getUuid()); assertEquals(newInfo.getUuid(), server.getUuid());
} }
protected void checkCreatedServer() { protected void checkStartedServer() {
System.out.println(new Gson().toJson(server)); System.out.println(new Gson().toJson(server));
assertNotNull(server.getUuid()); assertNotNull(server.getUuid());
assertNotNull(server.getUser()); assertNotNull(server.getUser());
@ -237,12 +240,8 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
assertEquals(server.getDevices(), assertEquals(server.getDevices(),
ImmutableMap.of("ide:0:0", new IDEDevice.Builder(0, 0).uuid(drive.getUuid()).build())); ImmutableMap.of("ide:0:0", new IDEDevice.Builder(0, 0).uuid(drive.getUuid()).build()));
assertEquals(server.getBootDeviceIds(), ImmutableSet.of("ide:0:0")); assertEquals(server.getBootDeviceIds(), ImmutableSet.of("ide:0:0"));
assertEquals(server.getNics(), ImmutableSet.of(new NIC.Builder() assertEquals(server.getNics().get(0).getDhcp(), server.getVnc().getIp());
.dhcp(server.getVnc().getIp()) assertEquals(server.getNics().get(0).getModel(), Model.E1000);
.model(Model.E1000)
.block(
ImmutableList.of("tcp/43594", "tcp/5902", "udp/5060", "tcp/5900", "tcp/5901", "tcp/21", "tcp/22",
"tcp/23", "tcp/25", "tcp/110", "tcp/143", "tcp/43595")).build()));
assertEquals(server.getStatus(), ServerStatus.ACTIVE); assertEquals(server.getStatus(), ServerStatus.ACTIVE);
} }
@ -285,9 +284,13 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
assertNotNull(server2.getUuid(), server.getUuid()); assertNotNull(server2.getUuid(), server.getUuid());
assertEquals(server2.getName(), "rediculous"); assertEquals(server2.getName(), "rediculous");
checkTagsAndMetadata(server2);
server = server2;
}
protected void checkTagsAndMetadata(ServerInfo server2) {
assertEquals(server2.getTags(), ImmutableSet.of("networking", "security", "gateway")); assertEquals(server2.getTags(), ImmutableSet.of("networking", "security", "gateway"));
assertEquals(server2.getUserMetadata(), ImmutableMap.of("foo", "bar")); assertEquals(server2.getUserMetadata(), ImmutableMap.of("foo", "bar"));
server = server2;
} }
@Test(dependsOnMethods = "testSetServerConfiguration") @Test(dependsOnMethods = "testSetServerConfiguration")