diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java index 4a0ba2fe95..e70ea6c2f2 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java @@ -28,19 +28,28 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; +import org.jclouds.cloudsigma.binders.BindCloneDriveOptionsToPlainTextString; import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo; 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.ElasticStackClient; import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString; import org.jclouds.elasticstack.binders.BindDriveToPlainTextString; +import org.jclouds.elasticstack.binders.BindServerToPlainTextString; import org.jclouds.elasticstack.domain.Drive; 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.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.BinderParam; 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.ResponseParser; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; @@ -84,7 +93,17 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient { ListenableFuture> listStandardImages(); /** - * @see ElasticStackClient#listDriveInfo() + * @see CloudSigmaClient#cloneDrive + */ + @POST + @ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class) + @Path("/drives/{uuid}/clone") + @MapBinder(BindCloneDriveOptionsToPlainTextString.class) + ListenableFuture cloneDrive(@PathParam("uuid") String sourceUuid, + @MapPayloadParam("name") String newName, CloneDriveOptions... options); + + /** + * {@inheritDoc} */ @Override @GET @@ -93,7 +112,7 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient { ListenableFuture> listDriveInfo(); /** - * @see ElasticStackClient#getDriveInfo + * {@inheritDoc} */ @Override @GET @@ -103,7 +122,7 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient { ListenableFuture getDriveInfo(@PathParam("uuid") String uuid); /** - * @see ElasticStackClient#createDrive + * {@inheritDoc} */ @Override @POST @@ -113,12 +132,53 @@ public interface CloudSigmaAsyncClient extends CommonElasticStackAsyncClient { ListenableFuture createDrive(@BinderParam(BindDriveToPlainTextString.class) Drive createDrive); /** - * @see ElasticStackClient#setDriveData + * {@inheritDoc} */ + @Override @POST - @ExceptionParser(ReturnNullOnNotFoundOr404.class) @ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class) @Path("/drives/{uuid}/set") ListenableFuture setDriveData(@PathParam("uuid") String uuid, @BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive); + + /** + * {@inheritDoc} + */ + @Override + @POST + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) + @Path("/servers/create") + ListenableFuture createServer( + @BinderParam(BindServerToPlainTextString.class) Server createServer); + + /** + * {@inheritDoc} + */ + @Override + @GET + @Path("/servers/info") + @ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class) + ListenableFuture> listServerInfo(); + + /** + * {@inheritDoc} + */ + @Override + @GET + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) + @Path("/servers/{uuid}/info") + ListenableFuture getServerInfo(@PathParam("uuid") String uuid); + + /** + * {@inheritDoc} + */ + @Override + @POST + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) + @Path("/servers/{uuid}/set") + ListenableFuture setServerConfiguration(@PathParam("uuid") String uuid, + @BinderParam(BindServerToPlainTextString.class) Server setServer); } diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java index ecf4394a63..5ac74140ba 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.cloudsigma.domain.DriveInfo; +import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.concurrent.Timeout; import org.jclouds.elasticstack.CommonElasticStackClient; import org.jclouds.elasticstack.domain.Drive; @@ -60,6 +61,19 @@ public interface CloudSigmaClient extends CommonElasticStackClient { */ Set 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} */ diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextString.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextString.java new file mode 100644 index 0000000000..9cfb13b671 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextString.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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 postParams) { + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + "this binder is only valid for GeneratedHttpRequests!"); + @SuppressWarnings("unchecked") + GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; + checkState(gRequest.getArgs() != null, "args should be initialized at this point"); + + CloneDriveOptions options = findOptionsInArgsOrNull(gRequest); + if (options != null) { + postParams = ImmutableMap. 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(); + } + +} diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java index e935551866..c187dadc17 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java @@ -26,11 +26,13 @@ import org.jclouds.cloudsigma.CloudSigmaAsyncClient; import org.jclouds.cloudsigma.CloudSigmaClient; import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap; import org.jclouds.cloudsigma.functions.DriveDataToMap; +import org.jclouds.cloudsigma.functions.ServerToMap; import org.jclouds.elasticstack.domain.Device; import org.jclouds.elasticstack.domain.Drive; import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveMetrics; import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.elasticstack.domain.Server; import org.jclouds.elasticstack.domain.ServerMetrics; import org.jclouds.elasticstack.functions.MapToDevices; import org.jclouds.elasticstack.functions.MapToDevices.DeviceToId; @@ -86,6 +88,8 @@ public class CloudSigmaRestClientModule extends RestClientModule>() { }).to(DeviceToId.class); + bind(new TypeLiteral>>() { + }).to(ServerToMap.class); } @Override diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/DriveDataToMap.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/DriveDataToMap.java index 715098e6b8..baa1c0301e 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/DriveDataToMap.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/DriveDataToMap.java @@ -29,7 +29,6 @@ import javax.inject.Singleton; import org.jclouds.elasticstack.domain.DriveData; import com.google.common.base.Function; -import com.google.common.collect.Maps; /** * @@ -46,14 +45,6 @@ public class DriveDataToMap implements Function> @Override public Map apply(DriveData from) { - return Maps.transformEntries(renameKey(baseDriveToMap.apply(from), "tags", "use"), - new Maps.EntryTransformer() { - - @Override - public String transformEntry(String arg0, String arg1) { - return "use".equals(arg0) ? arg1.replace(' ', ',') : arg1; - } - - }); + return renameKey(baseDriveToMap.apply(from), "tags", "use"); } } \ No newline at end of file diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java new file mode 100644 index 0000000000..32224ed897 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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 { + private final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser; + + @Inject + public KeyValuesDelimitedByBlankLinesToServerInfo(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser) { + this.setParser = setParser; + } + + @Override + public ServerInfo apply(HttpResponse response) { + Set drives = setParser.apply(response); + if (drives.size() == 0) + return null; + return Iterables.get(drives, 0); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java new file mode 100644 index 0000000000..1726d153a1 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java @@ -0,0 +1,62 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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> { + 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 apply(HttpResponse response) { + String text = returnStringIf200.apply(response); + if (text == null || text.trim().equals("")) + return ImmutableSet. of(); + return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToServer)); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToDriveInfo.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToDriveInfo.java index 2910718e2a..45af167398 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToDriveInfo.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToDriveInfo.java @@ -50,7 +50,7 @@ public class MapToDriveInfo implements Function, DriveInfo> return null; DriveInfo.Builder builder = DriveInfo.Builder.fromDriveInfo(mapToDriveInfo.apply(from)); if (from.containsKey("use")) - builder.tags(Splitter.on(',').split(from.get("use"))); + builder.tags(Splitter.on(' ').split(from.get("use"))); if (from.containsKey("bits")) builder.bits(new Integer(from.get("bits"))); if (from.containsKey("url")) diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToServerInfo.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToServerInfo.java new file mode 100644 index 0000000000..d4ec8c2512 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/MapToServerInfo.java @@ -0,0 +1,95 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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, ServerInfo> { + private final Function, Map> mapToDevices; + private final Function, ServerMetrics> mapToMetrics; + private final Function, List> mapToNICs; + + @Inject + public MapToServerInfo(Function, Map> mapToDevices, + Function, ServerMetrics> mapToMetrics, Function, List> mapToNICs) { + this.mapToDevices = mapToDevices; + this.mapToMetrics = mapToMetrics; + this.mapToNICs = mapToNICs; + } + + @Override + public ServerInfo apply(Map 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 metadata = Maps.newLinkedHashMap(); + for (Entry 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(); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ServerToMap.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ServerToMap.java new file mode 100644 index 0000000000..8a5bfab146 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/functions/ServerToMap.java @@ -0,0 +1,83 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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> { + @Override + public Map apply(Server from) { + checkNotNull(from, "server"); + ImmutableMap.Builder 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 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 entry : from.getUserMetadata().entrySet()) + builder.put("user:" + entry.getKey(), entry.getValue()); + return builder.build(); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/options/CloneDriveOptions.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/options/CloneDriveOptions.java new file mode 100644 index 0000000000..df9f5c59a2 --- /dev/null +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/options/CloneDriveOptions.java @@ -0,0 +1,72 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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.

+ * Usage

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): + *

+ * + * import static org.jclouds.cloudsigma.options.CloneDriveOptions.Builder.*; + * + * + * Payload payload = client.cloneDrive("drive-uuid","newName", size(2*1024*1024l)); + * + * + * @author Adrian Cole + * + */ +public class CloneDriveOptions { + private final Map 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 getOptions() { + return ImmutableMap.copyOf(options); + } +} diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java index 51039a819d..9eebec7f9c 100644 --- a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java @@ -26,22 +26,31 @@ import java.lang.reflect.Method; import java.util.Properties; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo; 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.Drive; import org.jclouds.elasticstack.domain.DriveData; +import org.jclouds.elasticstack.domain.Server; import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.http.HttpRequest; import org.jclouds.http.filters.BasicAuthentication; +import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextSpec; +import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.RestAnnotationProcessor; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.inject.TypeLiteral; /** @@ -131,7 +140,8 @@ public class CloudSigmaAsyncClientTest extends RestClientTest 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"); assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); @@ -145,6 +155,41 @@ public class CloudSigmaAsyncClientTest extends RestClientTest 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 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 { Method method = CloudSigmaAsyncClient.class.getMethod("setDriveData", String.class, DriveData.class); GeneratedHttpRequest httpRequest = processor.createRequest(method, "100", @@ -152,16 +197,231 @@ public class CloudSigmaAsyncClientTest extends RestClientTest 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 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 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); checkFilters(httpRequest); } + public void testCreateServer() throws SecurityException, NoSuchMethodException, IOException { + Method method = CloudSigmaAsyncClient.class.getMethod("createServer", Server.class); + GeneratedHttpRequest 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 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 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 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 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 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 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 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 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 protected void checkFilters(HttpRequest request) { assertEquals(request.getFilters().size(), 1); diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java index d2ba081591..fd553233ca 100644 --- a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/CloudSigmaClientLiveTest.java @@ -26,9 +26,14 @@ import java.util.Set; import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.DriveType; +import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.elasticstack.CommonElasticStackClientLiveTest; +import org.jclouds.elasticstack.domain.ServerInfo; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + /** * Tests behavior of {@code CloudSigmaClient} * @@ -39,6 +44,8 @@ public class CloudSigmaClientLiveTest extends CommonElasticStackClientLiveTest drives = client.listStandardImages(); assertNotNull(drives); } + @Override protected void checkDriveMatchesGet(org.jclouds.elasticstack.domain.DriveInfo newInfo) { super.checkDriveMatchesGet(newInfo); @@ -72,7 +80,17 @@ public class CloudSigmaClientLiveTest extends CommonElasticStackClientLiveTest of()); + assertEquals(server2.getUserMetadata(), ImmutableMap. of()); } } diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextStringTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextStringTest.java new file mode 100644 index 0000000000..8f9d0a5769 --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/binders/BindCloneDriveOptionsToPlainTextStringTest.java @@ -0,0 +1,78 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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 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); + } + +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToDriveInfoTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToDriveInfoTest.java index aeff757ebf..2def4841fb 100644 --- a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToDriveInfoTest.java +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToDriveInfoTest.java @@ -45,6 +45,6 @@ public class KeyValuesDelimitedByBlankLinesToDriveInfoTest { public void testOne() { assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class - .getResourceAsStream("/drive.txt")))), MapToDriveInfoTest.ONE); + .getResourceAsStream("/cloudsigma/drive.txt")))), MapToDriveInfoTest.ONE); } } diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfoTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfoTest.java new file mode 100644 index 0000000000..6a8575b35d --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToServerInfoTest.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Map>>() { + }).to(MapToDevices.class); + bind(new TypeLiteral, Map>>() { + }).to(MapToDriveMetrics.class); + bind(new TypeLiteral, ServerMetrics>>() { + }).to(MapToServerMetrics.class); + bind(new TypeLiteral>() { + }).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); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest.java index 28e6f2ab3a..ed92403cc2 100644 --- a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest.java +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest.java @@ -47,6 +47,6 @@ public class ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSetTest { public void testOne() { assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToDriveInfoTest.class - .getResourceAsStream("/drive.txt")))), ImmutableSet. of(MapToDriveInfoTest.ONE)); + .getResourceAsStream("/cloudsigma/drive.txt")))), ImmutableSet. of(MapToDriveInfoTest.ONE)); } } diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java new file mode 100644 index 0000000000..2cf011cb15 --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Map>>() { + }).to(MapToDevices.class); + bind(new TypeLiteral, Map>>() { + }).to(MapToDriveMetrics.class); + bind(new TypeLiteral, ServerMetrics>>() { + }).to(MapToServerMetrics.class); + bind(new TypeLiteral>() { + }).to(DeviceToId.class); + } + + }).getInstance(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class); + + public void testNone() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), + ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", null)), ImmutableSet. of()); + } + + public void testOne() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class + .getResourceAsStream("/servers.txt")))), ImmutableSet. of(MapToServerInfoTest.ONE, + MapToServerInfoTest.TWO)); + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToDriveInfoTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToDriveInfoTest.java index e630bf4572..39ef3bdf2e 100644 --- a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToDriveInfoTest.java +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToDriveInfoTest.java @@ -90,7 +90,7 @@ public class MapToDriveInfoTest { public void testComplete() throws IOException { Map 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); diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToServerInfoTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToServerInfoTest.java new file mode 100644 index 0000000000..e9fc095742 --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/MapToServerInfoTest.java @@ -0,0 +1,167 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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. 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 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 input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply( + Utils.toStringAndClose(MapToServerInfoTest.class.getResourceAsStream("/new_server.txt"))).get(0); + + assertEquals(MAP_TO_DRIVE.apply(input), NEW); + + } +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ServerToMapTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ServerToMapTest.java new file mode 100644 index 0000000000..744f6aafb8 --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/functions/ServerToMapTest.java @@ -0,0 +1,66 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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()); + } + +} \ No newline at end of file diff --git a/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/options/CloneDriveOptionsTest.java b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/options/CloneDriveOptionsTest.java new file mode 100644 index 0000000000..960cb766fb --- /dev/null +++ b/sandbox/cloudsigma/src/test/java/org/jclouds/cloudsigma/options/CloneDriveOptionsTest.java @@ -0,0 +1,59 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.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); + } + +} diff --git a/sandbox/cloudsigma/src/test/resources/drive.txt b/sandbox/cloudsigma/src/test/resources/cloudsigma/drive.txt similarity index 97% rename from sandbox/cloudsigma/src/test/resources/drive.txt rename to sandbox/cloudsigma/src/test/resources/cloudsigma/drive.txt index 04372bb776..63abfc8f14 100644 --- a/sandbox/cloudsigma/src/test/resources/drive.txt +++ b/sandbox/cloudsigma/src/test/resources/cloudsigma/drive.txt @@ -1,5 +1,5 @@ status active -use networking,security,gateway +use networking security gateway name Ubuntu 10.10 Server Edition Linux 64bit Preinstalled System bits 64 url http://www.ubuntu.com diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java index 2ef61f6e9e..43ddd019cc 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java @@ -88,16 +88,6 @@ public interface CommonElasticStackAsyncClient { @Path("/servers/{uuid}/info") ListenableFuture getServerInfo(@PathParam("uuid") String uuid); - /** - * @see ElasticStackClient#createAndStartServer - */ - @POST - @ExceptionParser(ReturnNullOnNotFoundOr404.class) - @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) - @Path("/servers/create") - ListenableFuture createAndStartServer( - @BinderParam(BindServerToPlainTextString.class) Server createServer); - /** * @see ElasticStackClient#createServer */ @@ -109,7 +99,7 @@ public interface CommonElasticStackAsyncClient { @BinderParam(BindServerToPlainTextString.class) Server createServer); /** - * @see ElasticStackClient#setServer + * @see ElasticStackClient#setServerConfiguration */ @POST @ExceptionParser(ReturnNullOnNotFoundOr404.class) diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java index 5839248f6b..78632ca642 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java @@ -68,14 +68,6 @@ public interface CommonElasticStackClient { */ ServerInfo createServer(Server server); - /** - * create and start a new server - * - * @param server - * @return newly created server - */ - ServerInfo createAndStartServer(Server server); - /** * set server configuration * diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackAsyncClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackAsyncClient.java index cea0b3c52f..30423756a1 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackAsyncClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackAsyncClient.java @@ -26,10 +26,15 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import org.jclouds.elasticstack.binders.BindServerToPlainTextString; 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.http.filters.BasicAuthentication; import org.jclouds.io.Payload; +import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; @@ -50,6 +55,16 @@ import com.google.common.util.concurrent.ListenableFuture; @Consumes(MediaType.TEXT_PLAIN) public interface ElasticStackAsyncClient extends CommonElasticStackAsyncClient { + /** + * @see ElasticStackClient#createAndStartServer + */ + @POST + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) + @Path("/servers/create") + ListenableFuture createAndStartServer( + @BinderParam(BindServerToPlainTextString.class) Server createServer); + /** * @see ElasticStackClient#imageDrive(String,String) */ diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackClient.java index 129ac4a94f..7fb5631415 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackClient.java @@ -23,6 +23,8 @@ import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; import org.jclouds.elasticstack.domain.ImageConversionType; +import org.jclouds.elasticstack.domain.Server; +import org.jclouds.elasticstack.domain.ServerInfo; import org.jclouds.io.Payload; /** @@ -36,6 +38,14 @@ import org.jclouds.io.Payload; @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) 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 * reported via drive info. diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java index 6e88d05692..2ed5bf7f9e 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java @@ -83,8 +83,6 @@ public class ElasticStackRestClientModule extends RestClientModule>>() { }).to(ServerToMap.class); - bind(new TypeLiteral>>() { - }).to(ServerToMap.class); } @Override diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java index c553edd6de..371977f9db 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java @@ -37,6 +37,7 @@ public class NIC { private Model model; private String vlan; private String mac; + // TODO elasticstack specific private Set block = ImmutableSet.of(); public Builder dhcp(String dhcp) { diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java index 018909bee1..ceda1d3e51 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java @@ -46,7 +46,7 @@ public class Server extends Item { protected Set bootDeviceIds = ImmutableSet.of(); protected List nics = ImmutableList.of(); protected VNC vnc; - // TODO undocumented + // TODO cloudsigma specific protected String description; public Builder cpu(int cpu) { diff --git a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java index 7a08fd4f3f..3906f67088 100644 --- a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java +++ b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java @@ -36,7 +36,6 @@ import org.jclouds.elasticstack.domain.DriveInfo; import org.jclouds.elasticstack.domain.DriveStatus; 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.ServerInfo; 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.Predicates; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.gson.Gson; @@ -68,7 +66,9 @@ import com.google.inject.Module; @Test(groups = "live", sequential = true) public abstract class CommonElasticStackClientLiveTest { - 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 RestContext context; protected Predicate socketTester; @@ -109,9 +109,10 @@ public abstract class CommonElasticStackClientLiveTest(Predicates.not(new DriveClaimed(client)), 120, 1, + driveNotClaimed = new RetryablePredicate(Predicates.not(new DriveClaimed(client)), maxDriveImageTime, + 1, TimeUnit.SECONDS); + socketTester = new RetryablePredicate(new InetSocketAddressConnect(), maxDriveImageTime, 1, TimeUnit.SECONDS); - socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 120, 1, TimeUnit.SECONDS); } @Test @@ -159,7 +160,7 @@ public abstract class CommonElasticStackClientLiveTest