mirror of https://github.com/apache/jclouds.git
Issue 164: initial commit for slicehost. note this is not complete
This commit is contained in:
parent
7d1e4ff514
commit
d120b139fc
|
@ -47,6 +47,9 @@ ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
|
||||||
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
|
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
|
||||||
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
|
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
|
||||||
|
|
||||||
|
slicehost.contextbuilder=org.jclouds.slicehost.SlicehostContextBuilder
|
||||||
|
slicehost.propertiesbuilder=org.jclouds.slicehost.SlicehostPropertiesBuilder
|
||||||
|
|
||||||
trmk-vcloudexpress.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressContextBuilder
|
trmk-vcloudexpress.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressContextBuilder
|
||||||
trmk-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressPropertiesBuilder
|
trmk-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressPropertiesBuilder
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>jclouds-slicehost</artifactId>
|
||||||
|
<name>jclouds slicehost components</name>
|
||||||
|
<properties>
|
||||||
|
<jclouds.test.identity>${jclouds.slicehost.apikey}</jclouds.test.identity>
|
||||||
|
<jclouds.test.credential>${jclouds.slicehost.apikey}</jclouds.test.credential>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-compute</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-compute</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.14</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-log4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-jsch</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,204 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
|
||||||
|
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.SkipEncoding;
|
||||||
|
import org.jclouds.rest.annotations.XMLResponseParser;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.slicehost.binders.BindCreateSliceToXmlPayload;
|
||||||
|
import org.jclouds.slicehost.domain.Backup;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.jclouds.slicehost.domain.Image;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.jclouds.slicehost.filters.SlicehostBasic;
|
||||||
|
import org.jclouds.slicehost.xml.BackupHandler;
|
||||||
|
import org.jclouds.slicehost.xml.BackupsHandler;
|
||||||
|
import org.jclouds.slicehost.xml.FlavorHandler;
|
||||||
|
import org.jclouds.slicehost.xml.FlavorsHandler;
|
||||||
|
import org.jclouds.slicehost.xml.ImageHandler;
|
||||||
|
import org.jclouds.slicehost.xml.ImagesHandler;
|
||||||
|
import org.jclouds.slicehost.xml.SliceHandler;
|
||||||
|
import org.jclouds.slicehost.xml.SlicesHandler;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Slicehost via their REST API.
|
||||||
|
* <p/>
|
||||||
|
* All commands return a ListenableFuture of the result from Slicehost. Any
|
||||||
|
* exceptions incurred during processing will be wrapped in an
|
||||||
|
* {@link ExecutionException} as documented in {@link ListenableFuture#get()}.
|
||||||
|
*
|
||||||
|
* @see SlicehostClient
|
||||||
|
* @see <a href="http://www.slicehost.com/docs/Slicehost_API.pdf" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@SkipEncoding( { '/', '=' })
|
||||||
|
@RequestFilters(SlicehostBasic.class)
|
||||||
|
public interface SlicehostAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#listSlices
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/slices.xml")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
@XMLResponseParser(SlicesHandler.class)
|
||||||
|
ListenableFuture<? extends Set<Slice>> listSlices();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#getSlice
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@Path("/slices/{id}.xml")
|
||||||
|
@XMLResponseParser(SliceHandler.class)
|
||||||
|
ListenableFuture<Slice> getSlice(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#destroySlice
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Path("/slices/{id}/destroy.xml")
|
||||||
|
ListenableFuture<Void> destroySlice(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#rebootSlice
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/slices/{id}/reboot.xml")
|
||||||
|
ListenableFuture<Void> rebootSlice(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#hardRebootSlice
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/slices/{id}/hardReboot.xml")
|
||||||
|
ListenableFuture<Void> hardRebootSlice(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#createSlice
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/slices.xml")
|
||||||
|
@MapBinder(BindCreateSliceToXmlPayload.class)
|
||||||
|
@XMLResponseParser(SliceHandler.class)
|
||||||
|
ListenableFuture<Slice> createSlice(@MapPayloadParam("name") String name, @MapPayloadParam("image_id") int imageId,
|
||||||
|
@MapPayloadParam("flavor_id") int flavorId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#rebuildSliceFromImage
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/slices/{id}/rebuild.xml")
|
||||||
|
ListenableFuture<Void> rebuildSliceFromImage(@PathParam("id") int id, @QueryParam("image_id") int imageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#rebuildSliceFromBackup
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/slices/{id}/rebuild.xml")
|
||||||
|
ListenableFuture<Void> rebuildSliceFromBackup(@PathParam("id") int id, @QueryParam("backup_id") int imageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#listFlavors
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/flavors.xml")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
@XMLResponseParser(FlavorsHandler.class)
|
||||||
|
ListenableFuture<? extends Set<Flavor>> listFlavors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#getFlavor
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/flavors/{id}.xml")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@XMLResponseParser(FlavorHandler.class)
|
||||||
|
ListenableFuture<Flavor> getFlavor(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#listImages
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/images.xml")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
@XMLResponseParser(ImagesHandler.class)
|
||||||
|
ListenableFuture<? extends Set<Image>> listImages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#getImage
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@Path("/images/{id}.xml")
|
||||||
|
@XMLResponseParser(ImageHandler.class)
|
||||||
|
ListenableFuture<Image> getImage(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#destroyBackup
|
||||||
|
*/
|
||||||
|
@DELETE
|
||||||
|
@Path("/backups/{id}/destroy.xml")
|
||||||
|
ListenableFuture<Void> destroyBackup(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#listBackups
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/backups.xml")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
@XMLResponseParser(BackupsHandler.class)
|
||||||
|
ListenableFuture<? extends Set<Backup>> listBackups();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#getBackup
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@Path("/backups/{id}.xml")
|
||||||
|
@XMLResponseParser(BackupHandler.class)
|
||||||
|
ListenableFuture<Backup> getBackup(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SlicehostClient#createBackupFromSlice
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@Path("/backups.xml")
|
||||||
|
@XMLResponseParser(BackupHandler.class)
|
||||||
|
ListenableFuture<Backup> createBackupFromSlice(@QueryParam("slice_id") int sliceId);
|
||||||
|
|
||||||
|
}
|
|
@ -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.slicehost;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.slicehost.domain.Backup;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.jclouds.slicehost.domain.Image;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides access to Slicehost via their REST API.
|
||||||
|
* <p/>
|
||||||
|
* All commands return a ListenableFuture of the result from Slicehost. Any
|
||||||
|
* exceptions incurred during processing will be wrapped in an
|
||||||
|
* {@link ExecutionException} as documented in {@link ListenableFuture#get()}.
|
||||||
|
*
|
||||||
|
* @see SlicehostAsyncClient
|
||||||
|
* @see <a href="http://www.slicehost.com/docs/Slicehost_API.pdf" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface SlicehostClient {
|
||||||
|
Set<Slice> listSlices();
|
||||||
|
|
||||||
|
Slice getSlice(int id);
|
||||||
|
|
||||||
|
Void destroySlice(int id);
|
||||||
|
|
||||||
|
Void rebootSlice(int id);
|
||||||
|
|
||||||
|
Void hardRebootSlice(int id);
|
||||||
|
|
||||||
|
Slice createSlice(String name, int imageId, int flavorId);
|
||||||
|
|
||||||
|
Void rebuildSliceFromImage(int id, int imageId);
|
||||||
|
|
||||||
|
Void rebuildSliceFromBackup(int id, int imageId);
|
||||||
|
|
||||||
|
Set<Flavor> listFlavors();
|
||||||
|
|
||||||
|
Flavor getFlavor(int id);
|
||||||
|
|
||||||
|
Set<Image> listImages();
|
||||||
|
|
||||||
|
Image getImage(int id);
|
||||||
|
|
||||||
|
Void destroyBackup(int id);
|
||||||
|
|
||||||
|
Set<Backup> listBackups();
|
||||||
|
|
||||||
|
Backup getBackup(int id);
|
||||||
|
|
||||||
|
Backup createBackupFromSlice(int sliceId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.slicehost.compute.config.SlicehostComputeServiceContextModule;
|
||||||
|
import org.jclouds.slicehost.config.SlicehostRestClientModule;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates {@link SlicehostComputeServiceContext} or {@link Injector} instances based on the most
|
||||||
|
* commonly requested arguments.
|
||||||
|
* <p/>
|
||||||
|
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||||
|
* <p/>
|
||||||
|
* <p/>
|
||||||
|
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||||
|
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see SlicehostComputeServiceContext
|
||||||
|
*/
|
||||||
|
public class SlicehostContextBuilder extends
|
||||||
|
ComputeServiceContextBuilder<SlicehostClient, SlicehostAsyncClient> {
|
||||||
|
|
||||||
|
public SlicehostContextBuilder(Properties props) {
|
||||||
|
super(SlicehostClient.class, SlicehostAsyncClient.class, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addContextModule(List<Module> modules) {
|
||||||
|
modules.add(new SlicehostComputeServiceContextModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addClientModule(List<Module> modules) {
|
||||||
|
modules.add(new SlicehostRestClientModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.PropertiesBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds properties used in Slicehost Connections
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SlicehostPropertiesBuilder extends PropertiesBuilder {
|
||||||
|
@Override
|
||||||
|
protected Properties defaultProperties() {
|
||||||
|
Properties properties = super.defaultProperties();
|
||||||
|
properties.setProperty(PROPERTY_ENDPOINT, "https://api.slicehost.com");
|
||||||
|
properties.setProperty(PROPERTY_API_VERSION, "1.0");
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlicehostPropertiesBuilder(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.rest.MapBinder;
|
||||||
|
import org.jclouds.rest.binders.BindToStringPayload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class BindCreateSliceToXmlPayload implements MapBinder {
|
||||||
|
private final BindToStringPayload binder;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
BindCreateSliceToXmlPayload(BindToStringPayload binder) {
|
||||||
|
this.binder = binder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bindToRequest(HttpRequest request, Map<String, String> postParams) {
|
||||||
|
String flavorId = checkNotNull(postParams.get("flavor_id"), "flavor_id");
|
||||||
|
String imageId = checkNotNull(postParams.get("image_id"), "image_id");
|
||||||
|
String name = checkNotNull(postParams.get("name"), "name");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><slice>");
|
||||||
|
builder.append("<flavor-id type=\"integer\">").append(flavorId).append("</flavor-id>");
|
||||||
|
builder.append("<image-id type=\"integer\">").append(imageId).append("</image-id>");
|
||||||
|
builder.append("<name>").append(name).append("</name>");
|
||||||
|
builder.append("</slice>");
|
||||||
|
binder.bindToRequest(request, builder.toString());
|
||||||
|
request.getPayload().setContentType(MediaType.APPLICATION_XML);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bindToRequest(HttpRequest request, Object input) {
|
||||||
|
throw new UnsupportedOperationException("should use map params");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,333 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.compute.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.LoadBalancerService;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceTimeoutsModule;
|
||||||
|
import org.jclouds.compute.domain.Architecture;
|
||||||
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Size;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
|
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
|
import org.jclouds.compute.internal.BaseComputeService;
|
||||||
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
|
import org.jclouds.compute.predicates.ImagePredicates;
|
||||||
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
|
||||||
|
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.rest.annotations.Provider;
|
||||||
|
import org.jclouds.rest.internal.RestContextImpl;
|
||||||
|
import org.jclouds.slicehost.SlicehostAsyncClient;
|
||||||
|
import org.jclouds.slicehost.SlicehostClient;
|
||||||
|
import org.jclouds.slicehost.compute.functions.SliceToNodeMetadata;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.Scopes;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.util.Providers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the {@link SlicehostComputeServiceContext}; requires
|
||||||
|
* {@link BaseComputeService} bound.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SlicehostComputeServiceContextModule extends AbstractModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
install(new ComputeServiceTimeoutsModule());
|
||||||
|
bind(new TypeLiteral<Function<Slice, NodeMetadata>>() {
|
||||||
|
}).to(SliceToNodeMetadata.class);
|
||||||
|
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null));
|
||||||
|
bind(new TypeLiteral<ComputeServiceContext>() {
|
||||||
|
}).to(new TypeLiteral<ComputeServiceContextImpl<SlicehostClient, SlicehostAsyncClient>>() {
|
||||||
|
}).in(Scopes.SINGLETON);
|
||||||
|
bind(new TypeLiteral<RestContext<SlicehostClient, SlicehostAsyncClient>>() {
|
||||||
|
}).to(new TypeLiteral<RestContextImpl<SlicehostClient, SlicehostAsyncClient>>() {
|
||||||
|
}).in(Scopes.SINGLETON);
|
||||||
|
bind(AddNodeWithTagStrategy.class).to(SlicehostAddNodeWithTagStrategy.class);
|
||||||
|
bind(ListNodesStrategy.class).to(SlicehostListNodesStrategy.class);
|
||||||
|
bind(GetNodeMetadataStrategy.class).to(SlicehostGetNodeMetadataStrategy.class);
|
||||||
|
bind(RebootNodeStrategy.class).to(SlicehostRebootNodeStrategy.class);
|
||||||
|
bind(DestroyNodeStrategy.class).to(SlicehostDestroyNodeStrategy.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Named("DEFAULT")
|
||||||
|
protected TemplateBuilder provideTemplate(TemplateBuilder template) {
|
||||||
|
return template.osFamily(UBUNTU).imageNameMatches(".*10\\.?04.*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Named("NAMING_CONVENTION")
|
||||||
|
@Singleton
|
||||||
|
String provideNamingConvention(@Named(Constants.PROPERTY_IDENTITY) String identity) {
|
||||||
|
return identity + "-%s-%s";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class SlicehostRebootNodeStrategy implements RebootNodeStrategy {
|
||||||
|
private final SlicehostClient client;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SlicehostRebootNodeStrategy(SlicehostClient client, GetNodeMetadataStrategy getNode) {
|
||||||
|
this.client = client;
|
||||||
|
this.getNode = getNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata execute(String id) {
|
||||||
|
int sliceId = Integer.parseInt(id);
|
||||||
|
client.hardRebootSlice(sliceId);
|
||||||
|
return getNode.execute(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class SlicehostDestroyNodeStrategy implements DestroyNodeStrategy {
|
||||||
|
private final SlicehostClient client;
|
||||||
|
private final GetNodeMetadataStrategy getNode;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SlicehostDestroyNodeStrategy(SlicehostClient client, GetNodeMetadataStrategy getNode) {
|
||||||
|
this.client = client;
|
||||||
|
this.getNode = getNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata execute(String id) {
|
||||||
|
int sliceId = Integer.parseInt(id);
|
||||||
|
// if false slice wasn't around in the first place
|
||||||
|
client.destroySlice(sliceId);
|
||||||
|
return getNode.execute(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class SlicehostAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
|
||||||
|
private final SlicehostClient client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SlicehostAddNodeWithTagStrategy(SlicehostClient client) {
|
||||||
|
this.client = checkNotNull(client, "client");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata execute(String tag, String name, Template template) {
|
||||||
|
Slice slice = client.createSlice(name, Integer.parseInt(template.getImage().getProviderId()), Integer
|
||||||
|
.parseInt(template.getSize().getProviderId()));
|
||||||
|
return new NodeMetadataImpl(slice.getId() + "", name, slice.getId() + "", template.getLocation(), null,
|
||||||
|
ImmutableMap.<String, String> of(), tag, template.getImage(), NodeState.PENDING, Iterables.filter(slice
|
||||||
|
.getAddresses(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return !input.startsWith("10.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}), Iterables.filter(slice.getAddresses(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return input.startsWith("10.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}), ImmutableMap.<String, String> of(), new Credentials("root", slice.getRootPassword()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class SlicehostListNodesStrategy implements ListNodesStrategy {
|
||||||
|
private final SlicehostClient client;
|
||||||
|
private final Function<Slice, NodeMetadata> sliceToNodeMetadata;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SlicehostListNodesStrategy(SlicehostClient client, Function<Slice, NodeMetadata> sliceToNodeMetadata) {
|
||||||
|
this.client = client;
|
||||||
|
this.sliceToNodeMetadata = sliceToNodeMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<? extends ComputeMetadata> list() {
|
||||||
|
return listDetailsOnNodesMatching(NodePredicates.all());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
|
||||||
|
return Iterables.filter(Iterables.transform(client.listSlices(), sliceToNodeMetadata), filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class SlicehostGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
|
||||||
|
|
||||||
|
private final SlicehostClient client;
|
||||||
|
private final Function<Slice, NodeMetadata> sliceToNodeMetadata;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected SlicehostGetNodeMetadataStrategy(SlicehostClient client,
|
||||||
|
Function<Slice, NodeMetadata> sliceToNodeMetadata) {
|
||||||
|
this.client = client;
|
||||||
|
this.sliceToNodeMetadata = sliceToNodeMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata execute(String id) {
|
||||||
|
int sliceId = Integer.parseInt(id);
|
||||||
|
Slice slice = client.getSlice(sliceId);
|
||||||
|
return slice == null ? null : sliceToNodeMetadata.apply(slice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
Map<Slice.Status, NodeState> provideSliceToNodeState() {
|
||||||
|
return ImmutableMap.<Slice.Status, NodeState> builder().put(Slice.Status.ACTIVE, NodeState.RUNNING)//
|
||||||
|
.put(Slice.Status.BUILD, NodeState.PENDING)//
|
||||||
|
.put(Slice.Status.REBOOT, NodeState.PENDING)//
|
||||||
|
.put(Slice.Status.HARD_REBOOT, NodeState.PENDING)//
|
||||||
|
.put(Slice.Status.TERMINATED, NodeState.TERMINATED)//
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Function<ComputeMetadata, String> indexer() {
|
||||||
|
return new Function<ComputeMetadata, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(ComputeMetadata from) {
|
||||||
|
return from.getProviderId();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Set<? extends Size> provideSizes(SlicehostClient sync, Set<? extends Image> images, Location location,
|
||||||
|
LogHolder holder, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||||
|
Function<ComputeMetadata, String> indexer) throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
|
final Set<Size> sizes = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing sizes");
|
||||||
|
for (final Flavor from : sync.listFlavors()) {
|
||||||
|
sizes.add(new SizeImpl(from.getId() + "", from.getName(), from.getId() + "", location, null, ImmutableMap
|
||||||
|
.<String, String> of(), from.getRam() / 1024.0, from.getRam(), (from.getRam() * 4) / 1024, ImagePredicates
|
||||||
|
.any()));
|
||||||
|
}
|
||||||
|
holder.logger.debug("<< sizes(%d)", sizes.size());
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LogHolder {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Pattern SLICEHOST_PATTERN = Pattern.compile("(([^ ]*) .*)");
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Location getLocation(@Provider String name) {
|
||||||
|
return new LocationImpl(LocationScope.PROVIDER, name, name, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
Set<? extends Location> provideLocations(Location location) {
|
||||||
|
return ImmutableSet.of(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Set<? extends Image> provideImages(final SlicehostClient sync, Location location, LogHolder holder,
|
||||||
|
Function<ComputeMetadata, String> indexer) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
final Set<Image> images = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing images");
|
||||||
|
for (final org.jclouds.slicehost.domain.Image from : sync.listImages()) {
|
||||||
|
OsFamily os = null;
|
||||||
|
Architecture arch = Architecture.X86_64;
|
||||||
|
String osDescription = "";
|
||||||
|
String version = "";
|
||||||
|
Matcher matcher = SLICEHOST_PATTERN.matcher(from.getName());
|
||||||
|
osDescription = from.getName();
|
||||||
|
if (matcher.find()) {
|
||||||
|
try {
|
||||||
|
os = OsFamily.fromValue(matcher.group(2).toLowerCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
holder.logger.debug("<< didn't match os(%s)", matcher.group(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images
|
||||||
|
.add(new ImageImpl(from.getId() + "", from.getName(), from.getId() + "", location, null, ImmutableMap
|
||||||
|
.<String, String> of(), from.getName(), version, os, osDescription, arch, new Credentials("root",
|
||||||
|
null)));
|
||||||
|
}
|
||||||
|
holder.logger.debug("<< images(%d)", images.size());
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.compute.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SliceToNodeMetadata implements Function<Slice, NodeMetadata> {
|
||||||
|
public static final Pattern SECOND_FIELD_DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX = Pattern
|
||||||
|
.compile("[^-]+-([^-]+)-[0-9a-f]+");
|
||||||
|
private final Location location;
|
||||||
|
private final Map<Slice.Status, NodeState> sliceToNodeState;
|
||||||
|
private final Set<? extends Image> images;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private static class FindImageForSlice implements Predicate<Image> {
|
||||||
|
private final Location location;
|
||||||
|
private final Slice instance;
|
||||||
|
|
||||||
|
private FindImageForSlice(Location location, Slice instance) {
|
||||||
|
this.location = location;
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Image input) {
|
||||||
|
return input.getProviderId().equals(instance.getImageId() + "")
|
||||||
|
&& (input.getLocation() == null || input.getLocation().equals(location.getParent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SliceToNodeMetadata(Map<Slice.Status, NodeState> sliceStateToNodeState, Set<? extends Image> images,
|
||||||
|
Location location) {
|
||||||
|
this.sliceToNodeState = checkNotNull(sliceStateToNodeState, "sliceStateToNodeState");
|
||||||
|
this.images = checkNotNull(images, "images");
|
||||||
|
this.location = checkNotNull(location, "location");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata apply(Slice from) {
|
||||||
|
Matcher matcher = SECOND_FIELD_DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from.getName());
|
||||||
|
final String tag = matcher.find() ? matcher.group(1) : null;
|
||||||
|
Image image = null;
|
||||||
|
try {
|
||||||
|
image = Iterables.find(images, new FindImageForSlice(location, from));
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
logger.warn("could not find a matching image for slice %s in location %s", from, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NodeMetadataImpl(from.getId() + "", from.getName(), from.getId() + "", location, null, ImmutableMap
|
||||||
|
.<String, String> of(), tag, image, sliceToNodeState.get(from.getStatus()), Iterables.filter(from
|
||||||
|
.getAddresses(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return !input.startsWith("10.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}), Iterables.filter(from.getAddresses(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return input.startsWith("10.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}), ImmutableMap.<String, String> of(), null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.config;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
import org.jclouds.http.annotation.ClientError;
|
||||||
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
import org.jclouds.slicehost.SlicehostAsyncClient;
|
||||||
|
import org.jclouds.slicehost.SlicehostClient;
|
||||||
|
import org.jclouds.slicehost.handlers.ParseSlicehostErrorFromHttpResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ConfiguresRestClient
|
||||||
|
@RequiresHttp
|
||||||
|
public class SlicehostRestClientModule extends RestClientModule<SlicehostClient, SlicehostAsyncClient> {
|
||||||
|
|
||||||
|
public SlicehostRestClientModule() {
|
||||||
|
super(SlicehostClient.class, SlicehostAsyncClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindErrorHandlers() {
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSlicehostErrorFromHttpResponse.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseSlicehostErrorFromHttpResponse.class);
|
||||||
|
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseSlicehostErrorFromHttpResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.domain;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class Backup {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String name;
|
||||||
|
private final String sliceId;
|
||||||
|
private final Date date;
|
||||||
|
|
||||||
|
public Backup(int id, String name, String sliceId, Date date) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.sliceId = sliceId;
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id of the backup
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Examples: weekly, my snapshot
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Slice this backup was made from
|
||||||
|
*/
|
||||||
|
public String getSliceId() {
|
||||||
|
return sliceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The time the backup was taken
|
||||||
|
*/
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((date == null) ? 0 : date.hashCode());
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + ((sliceId == null) ? 0 : sliceId.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Backup other = (Backup) obj;
|
||||||
|
if (date == null) {
|
||||||
|
if (other.date != null)
|
||||||
|
return false;
|
||||||
|
} else if (!date.equals(other.date))
|
||||||
|
return false;
|
||||||
|
if (id != other.id)
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
if (sliceId == null) {
|
||||||
|
if (other.sliceId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!sliceId.equals(other.sliceId))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[date=" + date + ", id=" + id + ", name=" + name + ", sliceId=" + sliceId + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* A flavor is an available hardware configuration for a slice.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class Flavor {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String name;
|
||||||
|
private final int price;
|
||||||
|
private final int ram;
|
||||||
|
|
||||||
|
public Flavor(int id, String name, int price, int ram) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.price = price;
|
||||||
|
this.ram = ram;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id of the flavor
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Verbose name for the flavor, e.g. Ò256 sliceÓ
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The price as an integer of cents. For example: 2000 equals $20.00.
|
||||||
|
* Note that all prices are in USD
|
||||||
|
*/
|
||||||
|
public int getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The amount of RAM (in Megabytes) included with the plan
|
||||||
|
*/
|
||||||
|
public int getRam() {
|
||||||
|
return ram;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + Float.floatToIntBits(price);
|
||||||
|
result = prime * result + ram;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Flavor other = (Flavor) obj;
|
||||||
|
if (id != other.id)
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(price) != Float.floatToIntBits(other.price))
|
||||||
|
return false;
|
||||||
|
if (ram != other.ram)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[id=" + id + ", name=" + name + ", price=" + price + ", ram=" + ram + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.slicehost.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class Image {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Image(int id, String name) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id of the image
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Example: Ubuntu 8.04 LTS (hardy)
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Image other = (Image) obj;
|
||||||
|
if (id != other.id)
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[id=" + id + ", name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.domain;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.base.CaseFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slice is a virtual machine instance in the Slicehost system. Flavor and
|
||||||
|
* image are requisite elements when creating a slice.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class Slice {
|
||||||
|
/**
|
||||||
|
* The current status of the slice
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum Status {
|
||||||
|
|
||||||
|
ACTIVE, BUILD, REBOOT, HARD_REBOOT, TERMINATED;
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_UNDERSCORE, name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Status fromValue(String state) {
|
||||||
|
return valueOf(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String name;
|
||||||
|
private final int flavorId;
|
||||||
|
@Nullable
|
||||||
|
private final Integer imageId;
|
||||||
|
@Nullable
|
||||||
|
private final Integer backupId;
|
||||||
|
private final Status status;
|
||||||
|
@Nullable
|
||||||
|
private final Integer progress;
|
||||||
|
private final float bandwidthIn;
|
||||||
|
private final float bandwidthOut;
|
||||||
|
private final Set<String> addresses;
|
||||||
|
@Nullable
|
||||||
|
private final String rootPassword;
|
||||||
|
|
||||||
|
public Slice(int id, String name, int flavorId, @Nullable Integer imageId, @Nullable Integer backupId,
|
||||||
|
Status status, @Nullable Integer progress, float bandwidthIn, float bandwidthOut, Set<String> addresses,
|
||||||
|
@Nullable String rootPassword) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.flavorId = flavorId;
|
||||||
|
this.imageId = imageId;
|
||||||
|
this.backupId = backupId;
|
||||||
|
this.status = status;
|
||||||
|
this.progress = progress;
|
||||||
|
this.bandwidthIn = bandwidthIn;
|
||||||
|
this.bandwidthOut = bandwidthOut;
|
||||||
|
this.addresses = addresses;
|
||||||
|
this.rootPassword = rootPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return unique id within slicehost
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A string to identify the slice
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the flavor of a slice
|
||||||
|
*/
|
||||||
|
public int getFlavorId() {
|
||||||
|
return flavorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the image used to create the slice or null
|
||||||
|
*/
|
||||||
|
public Integer getImageId() {
|
||||||
|
return imageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current status of the slice
|
||||||
|
*/
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The percentage of current action in percentage
|
||||||
|
*/
|
||||||
|
public Integer getProgress() {
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The incoming bandwidth total for this billing cycle, in Gigabytes
|
||||||
|
*/
|
||||||
|
public float getBandwidthIn() {
|
||||||
|
return bandwidthIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The outgoing bandwidth total for this billing cycle, in Gigabytes
|
||||||
|
*/
|
||||||
|
public float getBandwidthOut() {
|
||||||
|
return bandwidthOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return an array of strings representing the Slice's IPs, including
|
||||||
|
* private IPs
|
||||||
|
*/
|
||||||
|
public Set<String> getAddresses() {
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return root password, if just created
|
||||||
|
*/
|
||||||
|
public String getRootPassword() {
|
||||||
|
return rootPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return backup used to create this instance or null
|
||||||
|
*/
|
||||||
|
public Integer getBackupId() {
|
||||||
|
return backupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
|
||||||
|
result = prime * result + ((backupId == null) ? 0 : backupId.hashCode());
|
||||||
|
result = prime * result + Float.floatToIntBits(bandwidthIn);
|
||||||
|
result = prime * result + Float.floatToIntBits(bandwidthOut);
|
||||||
|
result = prime * result + flavorId;
|
||||||
|
result = prime * result + id;
|
||||||
|
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
result = prime * result + ((progress == null) ? 0 : progress.hashCode());
|
||||||
|
result = prime * result + ((rootPassword == null) ? 0 : rootPassword.hashCode());
|
||||||
|
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Slice other = (Slice) obj;
|
||||||
|
if (addresses == null) {
|
||||||
|
if (other.addresses != null)
|
||||||
|
return false;
|
||||||
|
} else if (!addresses.equals(other.addresses))
|
||||||
|
return false;
|
||||||
|
if (backupId == null) {
|
||||||
|
if (other.backupId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!backupId.equals(other.backupId))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(bandwidthIn) != Float.floatToIntBits(other.bandwidthIn))
|
||||||
|
return false;
|
||||||
|
if (Float.floatToIntBits(bandwidthOut) != Float.floatToIntBits(other.bandwidthOut))
|
||||||
|
return false;
|
||||||
|
if (flavorId != other.flavorId)
|
||||||
|
return false;
|
||||||
|
if (id != other.id)
|
||||||
|
return false;
|
||||||
|
if (imageId == null) {
|
||||||
|
if (other.imageId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!imageId.equals(other.imageId))
|
||||||
|
return false;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
if (progress == null) {
|
||||||
|
if (other.progress != null)
|
||||||
|
return false;
|
||||||
|
} else if (!progress.equals(other.progress))
|
||||||
|
return false;
|
||||||
|
if (rootPassword == null) {
|
||||||
|
if (other.rootPassword != null)
|
||||||
|
return false;
|
||||||
|
} else if (!rootPassword.equals(other.rootPassword))
|
||||||
|
return false;
|
||||||
|
if (status == null) {
|
||||||
|
if (other.status != null)
|
||||||
|
return false;
|
||||||
|
} else if (!status.equals(other.status))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[id=" + id + ", name=" + name + ", flavorId=" + flavorId + ", imageId=" + imageId + ", backupId="
|
||||||
|
+ backupId + ", status=" + status + ", progress=" + progress + ", bandwidthIn=" + bandwidthIn
|
||||||
|
+ ", bandwidthOut=" + bandwidthOut + ", addresses=" + addresses + ", rootPassword="
|
||||||
|
+ (rootPassword != null) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.filters;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.encryption.EncryptionService;
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SlicehostBasic implements HttpRequestFilter {
|
||||||
|
private final String apikey;
|
||||||
|
private final EncryptionService encryptionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SlicehostBasic(@Named(Constants.PROPERTY_IDENTITY) String apikey, EncryptionService encryptionService) {
|
||||||
|
this.apikey = checkNotNull(apikey, "apikey");
|
||||||
|
this.encryptionService = checkNotNull(encryptionService, "encryptionService");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filter(HttpRequest request) throws HttpException {
|
||||||
|
request.getHeaders().replaceValues("Authorization",
|
||||||
|
Collections.singleton(String.format("Basic %s", encryptionService.base64(apikey.getBytes()))));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package org.jclouds.slicehost.handlers;
|
||||||
|
|
||||||
|
import static org.jclouds.http.HttpUtils.releasePayload;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.http.functions.ParseSax.Factory;
|
||||||
|
import org.jclouds.io.Payload;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
import org.jclouds.slicehost.xml.ErrorHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will parse and set an appropriate exception on the command object.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ParseSlicehostErrorFromHttpResponse implements HttpErrorHandler {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
public static final Pattern RESOURCE_PATTERN = Pattern.compile("^/v1[^/]*/[0-9]+/([^/]+)/([0-9]+)");
|
||||||
|
|
||||||
|
private final ErrorParser errorParser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ParseSlicehostErrorFromHttpResponse(ErrorParser errorParser) {
|
||||||
|
this.errorParser = errorParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleError(HttpCommand command, HttpResponse response) {
|
||||||
|
Exception exception = new HttpResponseException(command, response);
|
||||||
|
try {
|
||||||
|
String content = response.getStatusCode() != 401 ? parseErrorFromContentOrNull(command, response) : null;
|
||||||
|
switch (response.getStatusCode()) {
|
||||||
|
case 401:
|
||||||
|
exception = new AuthorizationException(command.getRequest(), content);
|
||||||
|
break;
|
||||||
|
case 403:
|
||||||
|
case 404:
|
||||||
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
|
String path = command.getRequest().getEndpoint().getPath();
|
||||||
|
Matcher matcher = RESOURCE_PATTERN.matcher(path);
|
||||||
|
String message;
|
||||||
|
if (matcher.find()) {
|
||||||
|
message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
|
||||||
|
} else {
|
||||||
|
message = path;
|
||||||
|
}
|
||||||
|
exception = new ResourceNotFoundException(message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exception = new HttpResponseException(command, response, content);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
releasePayload(response);
|
||||||
|
command.setException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
static class ErrorParser {
|
||||||
|
final ParseSax.Factory factory;
|
||||||
|
final Provider<ErrorHandler> errorHandlerProvider;
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ErrorParser(Factory factory, Provider<ErrorHandler> errorHandlerProvider) {
|
||||||
|
this.factory = factory;
|
||||||
|
this.errorHandlerProvider = errorHandlerProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parse(Payload in) {
|
||||||
|
try {
|
||||||
|
return factory.create(errorHandlerProvider.get()).parse(in.getInput());
|
||||||
|
} catch (HttpException e) {
|
||||||
|
logger.warn(e, "error parsing error");
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
in.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
|
||||||
|
if (response.getPayload() != null) {
|
||||||
|
return errorParser.parse(response.getPayload());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package org.jclouds.slicehost.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.slicehost.SlicehostClient;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SliceActive implements Predicate<Slice> {
|
||||||
|
|
||||||
|
private final SlicehostClient client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SliceActive(SlicehostClient client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(Slice slice) {
|
||||||
|
logger.trace("looking for state on slice %s", checkNotNull(slice, "slice"));
|
||||||
|
slice = refresh(slice);
|
||||||
|
if (slice == null)
|
||||||
|
return false;
|
||||||
|
logger.trace("%s: looking for slice state %s: currently: %s", slice.getId(), Slice.Status.ACTIVE, slice
|
||||||
|
.getStatus());
|
||||||
|
return slice.getStatus() == Slice.Status.ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Slice refresh(Slice slice) {
|
||||||
|
return client.getSlice(slice.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
package org.jclouds.slicehost.predicates;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.slicehost.SlicehostClient;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class SliceTerminated implements Predicate<Slice> {
|
||||||
|
|
||||||
|
private final SlicehostClient client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SliceTerminated(SlicehostClient client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(Slice slice) {
|
||||||
|
logger.trace("looking for state on slice %s", checkNotNull(slice, "slice"));
|
||||||
|
slice = refresh(slice);
|
||||||
|
if (slice == null)
|
||||||
|
return true;
|
||||||
|
logger.trace("%s: looking for slice state %s: currently: %s", slice.getId(), Slice.Status.TERMINATED, slice
|
||||||
|
.getStatus());
|
||||||
|
return slice.getStatus() == Slice.Status.TERMINATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Slice refresh(Slice slice) {
|
||||||
|
return client.getSlice(slice.getId());
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.slicehost.domain.Backup;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class BackupHandler extends ParseSax.HandlerWithResult<Backup> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private String sliceId;
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
private Backup backup;
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
public Backup getResult() {
|
||||||
|
return backup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.equalsIgnoreCase("id")) {
|
||||||
|
id = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("name")) {
|
||||||
|
this.name = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("slice_id")) {
|
||||||
|
sliceId = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("date")) {
|
||||||
|
try {
|
||||||
|
date = DateFormat.getInstance().parse(currentText.toString().trim());
|
||||||
|
} catch (ParseException e) {
|
||||||
|
logger.warn(e, "error parsing: %s", currentText.toString().trim());
|
||||||
|
}
|
||||||
|
} else if (qName.equalsIgnoreCase("backup")) {
|
||||||
|
this.backup = new Backup(id, name, sliceId, date);
|
||||||
|
this.id = -1;
|
||||||
|
this.name = null;
|
||||||
|
this.sliceId = null;
|
||||||
|
this.date = null;
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Backup;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class BackupsHandler extends ParseSax.HandlerWithResult<Set<? extends Backup>> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private Set<Backup> backups = Sets.newLinkedHashSet();
|
||||||
|
private final BackupHandler locationHandler;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public BackupsHandler(BackupHandler locationHandler) {
|
||||||
|
this.locationHandler = locationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<? extends Backup> getResult() {
|
||||||
|
return backups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
locationHandler.startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
locationHandler.endElement(uri, localName, qName);
|
||||||
|
if (qName.equals("backup") && currentText.toString().trim().equals("")) {
|
||||||
|
this.backups.add(locationHandler.getResult());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
locationHandler.characters(ch, start, length);
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ErrorHandler extends ParseSax.HandlerWithResult<String> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private String error;
|
||||||
|
|
||||||
|
public String getResult() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.equalsIgnoreCase("error")) {
|
||||||
|
this.error = currentText.toString().trim();
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class FlavorHandler extends ParseSax.HandlerWithResult<Flavor> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private int price;
|
||||||
|
private int ram;
|
||||||
|
|
||||||
|
private Flavor flavor;
|
||||||
|
|
||||||
|
public Flavor getResult() {
|
||||||
|
return flavor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.equalsIgnoreCase("id")) {
|
||||||
|
id = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("name")) {
|
||||||
|
this.name = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("ram")) {
|
||||||
|
ram = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("price")) {
|
||||||
|
price = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("flavor")) {
|
||||||
|
this.flavor = new Flavor(id, name, price, ram);
|
||||||
|
this.id = -1;
|
||||||
|
this.name = null;
|
||||||
|
this.ram = -1;
|
||||||
|
this.price = 0;
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class FlavorsHandler extends ParseSax.HandlerWithResult<Set<? extends Flavor>> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private Set<Flavor> slices = Sets.newLinkedHashSet();
|
||||||
|
private final FlavorHandler locationHandler;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FlavorsHandler(FlavorHandler locationHandler) {
|
||||||
|
this.locationHandler = locationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<? extends Flavor> getResult() {
|
||||||
|
return slices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
locationHandler.startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
locationHandler.endElement(uri, localName, qName);
|
||||||
|
if (qName.equals("flavor") && currentText.toString().trim().equals("")) {
|
||||||
|
this.slices.add(locationHandler.getResult());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
locationHandler.characters(ch, start, length);
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.slicehost.xml;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.slicehost.domain.Image;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ImageHandler extends ParseSax.HandlerWithResult<Image> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Image image;
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
public Image getResult() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.equalsIgnoreCase("id")) {
|
||||||
|
id = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("name")) {
|
||||||
|
this.name = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("image")) {
|
||||||
|
this.image = new Image(id, name);
|
||||||
|
this.id = -1;
|
||||||
|
this.name = null;
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Image;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ImagesHandler extends ParseSax.HandlerWithResult<Set<? extends Image>> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private Set<Image> images = Sets.newLinkedHashSet();
|
||||||
|
private final ImageHandler locationHandler;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ImagesHandler(ImageHandler locationHandler) {
|
||||||
|
this.locationHandler = locationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<? extends Image> getResult() {
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
locationHandler.startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
locationHandler.endElement(uri, localName, qName);
|
||||||
|
if (qName.equals("image") && currentText.toString().trim().equals("")) {
|
||||||
|
this.images.add(locationHandler.getResult());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
locationHandler.characters(ch, start, length);
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.jclouds.slicehost.domain.Slice.Status;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.inject.internal.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SliceHandler extends ParseSax.HandlerWithResult<Slice> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private int flavorId;
|
||||||
|
@Nullable
|
||||||
|
private Integer imageId;
|
||||||
|
@Nullable
|
||||||
|
private Integer backupId;
|
||||||
|
private Status status;
|
||||||
|
@Nullable
|
||||||
|
private Integer progress;
|
||||||
|
private float bandwidthIn;
|
||||||
|
private float bandwidthOut;
|
||||||
|
private Set<String> addresses = Sets.newLinkedHashSet();
|
||||||
|
@Nullable
|
||||||
|
private String rootPassword;
|
||||||
|
|
||||||
|
private Slice slice;
|
||||||
|
|
||||||
|
public Slice getResult() {
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (qName.equalsIgnoreCase("id")) {
|
||||||
|
id = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("name")) {
|
||||||
|
this.name = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("flavor-id")) {
|
||||||
|
flavorId = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("image-id")) {
|
||||||
|
imageId = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("backup-id")) {
|
||||||
|
backupId = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("status")) {
|
||||||
|
this.status = Slice.Status.fromValue(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("progress")) {
|
||||||
|
progress = Integer.parseInt(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("bw-in")) {
|
||||||
|
bandwidthIn = Float.parseFloat(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("bw-out")) {
|
||||||
|
bandwidthOut = Float.parseFloat(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("address")) {
|
||||||
|
this.addresses.add(currentText.toString().trim());
|
||||||
|
} else if (qName.equalsIgnoreCase("root-password")) {
|
||||||
|
this.rootPassword = currentText.toString().trim();
|
||||||
|
} else if (qName.equalsIgnoreCase("slice")) {
|
||||||
|
this.slice = new Slice(id, name, flavorId, imageId, backupId, status, progress, bandwidthIn, bandwidthOut,
|
||||||
|
addresses, rootPassword);
|
||||||
|
this.id = -1;
|
||||||
|
this.name = null;
|
||||||
|
this.flavorId = -1;
|
||||||
|
this.imageId = null;
|
||||||
|
this.backupId = null;
|
||||||
|
this.status = null;
|
||||||
|
this.progress = null;
|
||||||
|
this.bandwidthIn = 0;
|
||||||
|
this.bandwidthOut = 0;
|
||||||
|
this.addresses = Sets.newLinkedHashSet();
|
||||||
|
this.rootPassword = null;
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SlicesHandler extends ParseSax.HandlerWithResult<Set<? extends Slice>> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
private Set<Slice> slices = Sets.newLinkedHashSet();
|
||||||
|
private final SliceHandler locationHandler;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SlicesHandler(SliceHandler locationHandler) {
|
||||||
|
this.locationHandler = locationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<? extends Slice> getResult() {
|
||||||
|
return slices;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
locationHandler.startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
locationHandler.endElement(uri, localName, qName);
|
||||||
|
if (qName.equals("slice") && currentText.toString().trim().equals("")) {
|
||||||
|
this.slices.add(locationHandler.getResult());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
locationHandler.characters(ch, start, length);
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ProvidersInPropertiesTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSupportedComputeServiceProviders() {
|
||||||
|
Iterable<String> providers = ComputeServiceUtils.getSupportedProviders();
|
||||||
|
assert Iterables.contains(providers, "slicehost") : providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSupportedProviders() {
|
||||||
|
Iterable<String> providers = Utils.getSupportedProviders();
|
||||||
|
assert Iterables.contains(providers, "slicehost") : providers;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,272 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.http.functions.ReleasePayloadAndReturn;
|
||||||
|
import org.jclouds.rest.RestClientTest;
|
||||||
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
import org.jclouds.rest.RestContextFactory.ContextSpec;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
|
import org.jclouds.slicehost.filters.SlicehostBasic;
|
||||||
|
import org.jclouds.slicehost.xml.FlavorHandler;
|
||||||
|
import org.jclouds.slicehost.xml.FlavorsHandler;
|
||||||
|
import org.jclouds.slicehost.xml.ImageHandler;
|
||||||
|
import org.jclouds.slicehost.xml.ImagesHandler;
|
||||||
|
import org.jclouds.slicehost.xml.SliceHandler;
|
||||||
|
import org.jclouds.slicehost.xml.SlicesHandler;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SlicehostClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "slicehost.SlicehostClientTest")
|
||||||
|
public class SlicehostAsyncClientTest extends RestClientTest<SlicehostAsyncClient> {
|
||||||
|
|
||||||
|
public void testCreateSlice() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("createSlice", String.class, int.class, int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, "ralphie", 2, 1);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "POST https://api.slicehost.com/slices.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(
|
||||||
|
request,
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><slice><flavor-id type=\"integer\">1</flavor-id><image-id type=\"integer\">2</image-id><name>ralphie</name></slice>",
|
||||||
|
"application/xml", false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, SliceHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDestroySlice() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("destroySlice", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "DELETE https://api.slicehost.com/slices/2/destroy.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListSlices() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("listSlices");
|
||||||
|
HttpRequest request = processor.createRequest(method);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/slices.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, SlicesHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetSlice() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("getSlice", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/slices/2.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, SliceHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListFlavors() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("listFlavors");
|
||||||
|
HttpRequest request = processor.createRequest(method);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/flavors.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, FlavorsHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetFlavor() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("getFlavor", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/flavors/2.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, FlavorHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImages() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("listImages");
|
||||||
|
HttpRequest request = processor.createRequest(method);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/images.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, ImagesHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetImage() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("getImage", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "GET https://api.slicehost.com/images/2.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, ImageHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDestroyBackup() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("destroyBackup", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "DELETE https://api.slicehost.com/backups/2/destroy.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRebuildSliceFromImage() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("rebuildSliceFromImage", int.class, int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 3, 1);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "PUT https://api.slicehost.com/slices/3/rebuild.xml?image_id=1 HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRebuildSliceFromBackup() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("rebuildSliceFromBackup", int.class, int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 3, 1);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "PUT https://api.slicehost.com/slices/3/rebuild.xml?backup_id=1 HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReboot() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("rebootSlice", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "PUT https://api.slicehost.com/slices/2/reboot.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testHardReboot() throws IOException, SecurityException, NoSuchMethodException {
|
||||||
|
Method method = SlicehostAsyncClient.class.getMethod("hardRebootSlice", int.class);
|
||||||
|
HttpRequest request = processor.createRequest(method, 2);
|
||||||
|
|
||||||
|
assertRequestLineEquals(request, "PUT https://api.slicehost.com/slices/2/hardReboot.xml HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TypeLiteral<RestAnnotationProcessor<SlicehostAsyncClient>> createTypeLiteral() {
|
||||||
|
return new TypeLiteral<RestAnnotationProcessor<SlicehostAsyncClient>>() {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkFilters(HttpRequest request) {
|
||||||
|
assertEquals(request.getFilters().size(), 1);
|
||||||
|
assertEquals(request.getFilters().get(0).getClass(), SlicehostBasic.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContextSpec<SlicehostClient, SlicehostAsyncClient> createContextSpec() {
|
||||||
|
return new RestContextFactory().createContextSpec("slicehost", "apikey", null, new Properties());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,342 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.io.Payloads;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
|
import org.jclouds.net.IPSocket;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.predicates.SocketOpen;
|
||||||
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
import org.jclouds.slicehost.domain.Backup;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.jclouds.slicehost.domain.Image;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
import org.jclouds.ssh.SshException;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SlicehostClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
// disabled [Web Hosting #129069
|
||||||
|
@Test(groups = "live", sequential = true, testName = "slicehost.SlicehostClientLiveTest")
|
||||||
|
public class SlicehostClientLiveTest {
|
||||||
|
|
||||||
|
protected SlicehostClient client;
|
||||||
|
protected SshClient.Factory sshFactory;
|
||||||
|
private Predicate<IPSocket> socketTester;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = { "live" })
|
||||||
|
public void setupClient() {
|
||||||
|
String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
|
||||||
|
|
||||||
|
Injector injector = new RestContextFactory().createContextBuilder("slicehost", identity, null,
|
||||||
|
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), new Properties())
|
||||||
|
.buildInjector();
|
||||||
|
|
||||||
|
client = injector.getInstance(SlicehostClient.class);
|
||||||
|
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||||
|
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||||
|
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 120, 1, TimeUnit.SECONDS);
|
||||||
|
injector.injectMembers(socketOpen); // add logger
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListSlices() throws Exception {
|
||||||
|
|
||||||
|
Set<Slice> response = client.listSlices();
|
||||||
|
assert null != response;
|
||||||
|
long initialContainerCount = response.size();
|
||||||
|
assertTrue(initialContainerCount >= 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListSlicesDetail() throws Exception {
|
||||||
|
Set<Slice> response = client.listSlices();
|
||||||
|
assert null != response;
|
||||||
|
long initialContainerCount = response.size();
|
||||||
|
assertTrue(initialContainerCount >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImages() throws Exception {
|
||||||
|
Set<Image> response = client.listImages();
|
||||||
|
assert null != response;
|
||||||
|
long imageCount = response.size();
|
||||||
|
assertTrue(imageCount >= 1);
|
||||||
|
for (Image image : response) {
|
||||||
|
assertTrue(image.getId() >= 0);
|
||||||
|
assert null != image.getName() : image;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImagesDetail() throws Exception {
|
||||||
|
Set<Image> response = client.listImages();
|
||||||
|
assert null != response;
|
||||||
|
long imageCount = response.size();
|
||||||
|
assertTrue(imageCount >= 0);
|
||||||
|
for (Image image : response) {
|
||||||
|
assertTrue(image.getId() >= 1);
|
||||||
|
assert null != image.getName() : image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetImagesDetail() throws Exception {
|
||||||
|
Set<Image> response = client.listImages();
|
||||||
|
assert null != response;
|
||||||
|
long imageCount = response.size();
|
||||||
|
assertTrue(imageCount >= 0);
|
||||||
|
for (Image image : response) {
|
||||||
|
try {
|
||||||
|
Image newDetails = client.getImage(image.getId());
|
||||||
|
assertEquals(image, newDetails);
|
||||||
|
} catch (HttpResponseException e) {// Ticket #9867
|
||||||
|
if (e.getResponse().getStatusCode() != 400)
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetImageDetailsNotFound() throws Exception {
|
||||||
|
assert client.getImage(12312987) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSliceDetailsNotFound() throws Exception {
|
||||||
|
assert client.getSlice(12312987) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetSlicesDetail() throws Exception {
|
||||||
|
Set<Slice> response = client.listSlices();
|
||||||
|
assert null != response;
|
||||||
|
long sliceCount = response.size();
|
||||||
|
assertTrue(sliceCount >= 0);
|
||||||
|
for (Slice slice : response) {
|
||||||
|
Slice newDetails = client.getSlice(slice.getId());
|
||||||
|
assertEquals(slice, newDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListFlavors() throws Exception {
|
||||||
|
Set<Flavor> response = client.listFlavors();
|
||||||
|
assert null != response;
|
||||||
|
long flavorCount = response.size();
|
||||||
|
assertTrue(flavorCount >= 1);
|
||||||
|
for (Flavor flavor : response) {
|
||||||
|
assertTrue(flavor.getId() >= 0);
|
||||||
|
assert null != flavor.getName() : flavor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListFlavorsDetail() throws Exception {
|
||||||
|
Set<Flavor> response = client.listFlavors();
|
||||||
|
assert null != response;
|
||||||
|
long flavorCount = response.size();
|
||||||
|
assertTrue(flavorCount >= 0);
|
||||||
|
for (Flavor flavor : response) {
|
||||||
|
assertTrue(flavor.getId() >= 1);
|
||||||
|
assert null != flavor.getName() : flavor;
|
||||||
|
assert -1 != flavor.getRam() : flavor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetFlavorsDetail() throws Exception {
|
||||||
|
Set<Flavor> response = client.listFlavors();
|
||||||
|
assert null != response;
|
||||||
|
long flavorCount = response.size();
|
||||||
|
assertTrue(flavorCount >= 0);
|
||||||
|
for (Flavor flavor : response) {
|
||||||
|
Flavor newDetails = client.getFlavor(flavor.getId());
|
||||||
|
assertEquals(flavor, newDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetFlavorDetailsNotFound() throws Exception {
|
||||||
|
assert client.getFlavor(12312987) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String slicePrefix = System.getProperty("user.name") + ".sh";
|
||||||
|
private int sliceId;
|
||||||
|
private String rootPassword;
|
||||||
|
private int backupId;
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testCreateSlice() throws Exception {
|
||||||
|
int imageId = 14362;
|
||||||
|
int flavorId = 1;
|
||||||
|
Slice slice = null;
|
||||||
|
while (slice == null) {
|
||||||
|
String sliceName = slicePrefix + "createslice" + new SecureRandom().nextInt();
|
||||||
|
try {
|
||||||
|
slice = client.createSlice(sliceName, imageId, flavorId);
|
||||||
|
} catch (UndeclaredThrowableException e) {
|
||||||
|
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
|
||||||
|
if (htpe.getResponse().getStatusCode() == 400)
|
||||||
|
continue;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertNotNull(slice.getRootPassword());
|
||||||
|
sliceId = slice.getId();
|
||||||
|
rootPassword = slice.getRootPassword();
|
||||||
|
assertEquals(slice.getStatus(), Slice.Status.BUILD);
|
||||||
|
blockUntilSliceActive(sliceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void blockUntilSliceActive(int sliceId) throws InterruptedException {
|
||||||
|
Slice currentDetails = null;
|
||||||
|
for (currentDetails = client.getSlice(sliceId); currentDetails.getStatus() != Slice.Status.ACTIVE; currentDetails = client
|
||||||
|
.getSlice(sliceId)) {
|
||||||
|
System.out.printf("blocking on status active%n%s%n", currentDetails);
|
||||||
|
Thread.sleep(5 * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateSlice")
|
||||||
|
public void testSliceDetails() throws Exception {
|
||||||
|
Slice slice = client.getSlice(sliceId);
|
||||||
|
assertEquals(slice.getStatus(), Slice.Status.ACTIVE);
|
||||||
|
assert slice.getProgress() >= 0 : "newDetails.getProgress()" + slice.getProgress();
|
||||||
|
assertEquals(new Integer(14362), slice.getImageId());
|
||||||
|
assertEquals(1, slice.getFlavorId());
|
||||||
|
assertNotNull(slice.getAddresses());
|
||||||
|
checkPassOk(slice, rootPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPassOk(Slice newDetails, String pass) throws IOException {
|
||||||
|
try {
|
||||||
|
doCreateMarkerFile(newDetails, pass);
|
||||||
|
} catch (SshException e) {// try twice in case there is a network timeout
|
||||||
|
try {
|
||||||
|
Thread.sleep(10 * 1000);
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
}
|
||||||
|
doCreateMarkerFile(newDetails, pass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doCreateMarkerFile(Slice newDetails, String pass) throws IOException {
|
||||||
|
String ip = getIp(newDetails);
|
||||||
|
IPSocket socket = new IPSocket(ip, 22);
|
||||||
|
socketTester.apply(socket);
|
||||||
|
|
||||||
|
SshClient client = sshFactory.create(socket, "root", pass);
|
||||||
|
try {
|
||||||
|
client.connect();
|
||||||
|
client.put("/etc/jclouds.txt", Payloads.newStringPayload("slicehost"));
|
||||||
|
} finally {
|
||||||
|
if (client != null)
|
||||||
|
client.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getIp(Slice newDetails) {
|
||||||
|
String ip = Iterables.find(newDetails.getAddresses(), new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return !input.startsWith("10.");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testSliceDetails")
|
||||||
|
public void testCreateBackup() throws Exception {
|
||||||
|
Backup backup = client.createBackupFromSlice(sliceId);
|
||||||
|
// TODO validate our request, as the above returns <nil-classes
|
||||||
|
// type="array"/>
|
||||||
|
assertEquals("hoofie", backup.getName());
|
||||||
|
assertEquals(new Integer(sliceId), backup.getSliceId());
|
||||||
|
backupId = backup.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testCreateBackup")
|
||||||
|
public void testRebuildSlice() throws Exception {
|
||||||
|
client.rebuildSliceFromBackup(sliceId, backupId);
|
||||||
|
blockUntilSliceActive(sliceId);
|
||||||
|
// issue Web Hosting #119580 imageId comes back incorrect after rebuild
|
||||||
|
// assertEquals(new Integer(imageId),
|
||||||
|
// client.getSlice(sliceId).getImageId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebuildSlice")
|
||||||
|
public void testRebootHard() throws Exception {
|
||||||
|
client.hardRebootSlice(sliceId);
|
||||||
|
blockUntilSliceActive(sliceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebootHard")
|
||||||
|
public void testRebootSoft() throws Exception {
|
||||||
|
client.rebootSlice(sliceId);
|
||||||
|
blockUntilSliceActive(sliceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testRebootSoft")
|
||||||
|
void testDeleteBackup() {
|
||||||
|
if (backupId > 0) {
|
||||||
|
client.destroyBackup(backupId);
|
||||||
|
assert client.getBackup(backupId) == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = "testDeleteBackup")
|
||||||
|
void destroySlice1() {
|
||||||
|
if (sliceId > 0) {
|
||||||
|
client.destroySlice(sliceId);
|
||||||
|
assert client.getSlice(sliceId) == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterTest
|
||||||
|
void destroySlicesOnEnd() {
|
||||||
|
if (sliceId > 0) {
|
||||||
|
client.destroySlice(sliceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.compute;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||||
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
|
import org.jclouds.compute.domain.Architecture;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.slicehost.SlicehostAsyncClient;
|
||||||
|
import org.jclouds.slicehost.SlicehostClient;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Generally disabled, as it incurs higher fees.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", enabled = true, sequential = true, testName = "slicehost.SlicehostComputeServiceLiveTest")
|
||||||
|
public class SlicehostComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
@Override
|
||||||
|
public void setServiceDefaults() {
|
||||||
|
provider = "slicehost";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilder() {
|
||||||
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getArchitecture(), Architecture.X86_64);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOsFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(defaultTemplate.getLocation().getId(), "slicehost");
|
||||||
|
assertEquals(defaultTemplate.getSize().getCores(), 0.25d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JschSshClientModule getSshModule() {
|
||||||
|
return new JschSshClientModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAssignability() throws Exception {
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
RestContext<SlicehostClient, SlicehostAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||||
|
.createContext(provider, identity, credential).getProviderSpecificContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
|
||||||
|
super.checkNodes(nodes, tag);
|
||||||
|
for (NodeMetadata node : nodes) {
|
||||||
|
assertEquals(node.getLocation().getScope(), LocationScope.HOST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code FlavorHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "slicehost.FlavorHandler")
|
||||||
|
public class FlavorHandlerTest extends BaseHandlerTest {
|
||||||
|
|
||||||
|
ParseSax<Flavor> createParser() {
|
||||||
|
ParseSax<Flavor> parser = (ParseSax<Flavor>) factory.create(injector.getInstance(FlavorHandler.class));
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_get_flavor.xml");
|
||||||
|
Flavor expects = new Flavor(1, "256 slice", 2000, 256);
|
||||||
|
|
||||||
|
assertEquals(createParser().parse(is), expects);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Flavor;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code FlavorsHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "slicehost.FlavorsHandler")
|
||||||
|
public class FlavorsHandlerTest extends BaseHandlerTest {
|
||||||
|
|
||||||
|
ParseSax<Set<? extends Flavor>> createParser() {
|
||||||
|
ParseSax<Set<? extends Flavor>> parser = (ParseSax<Set<? extends Flavor>>) factory.create(injector
|
||||||
|
.getInstance(FlavorsHandler.class));
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_list_flavors.xml");
|
||||||
|
Set<? extends Flavor> expects = ImmutableSet.of(new Flavor(1, "256 slice", 2000, 256), new Flavor(2, "512 slice",
|
||||||
|
3800, 512), new Flavor(3, "1GB slice", 7000, 1024), new Flavor(4, "2GB slice", 13000, 2048));
|
||||||
|
assertEquals(createParser().parse(is), expects);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.slicehost.xml;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SliceHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "slicehost.SliceHandler")
|
||||||
|
public class SliceHandlerTest extends BaseHandlerTest {
|
||||||
|
|
||||||
|
ParseSax<Slice> createParser() {
|
||||||
|
ParseSax<Slice> parser = (ParseSax<Slice>) factory.create(injector.getInstance(SliceHandler.class));
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_get_slice.xml");
|
||||||
|
Slice expects = new Slice(1, "jclouds-foo", 1, 10, null, Slice.Status.BUILD, 0, 0, 0, ImmutableSet.<String> of(
|
||||||
|
"174.143.212.229", "10.176.164.199"), null);
|
||||||
|
|
||||||
|
assertEquals(createParser().parse(is), expects);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNew() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_new_slice.xml");
|
||||||
|
Slice expects = new Slice(71907, "slicetest", 1, 11, null, Slice.Status.BUILD, 0, 0, 0, ImmutableSet.<String> of(
|
||||||
|
"10.176.168.15", "67.23.20.114"), "fooadfa1231");
|
||||||
|
|
||||||
|
assertEquals(createParser().parse(is), expects);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.slicehost.xml;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.slicehost.domain.Slice;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SlicesHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "slicehost.SlicesHandler")
|
||||||
|
public class SlicesHandlerTest extends BaseHandlerTest {
|
||||||
|
|
||||||
|
ParseSax<Set<? extends Slice>> createParser() {
|
||||||
|
ParseSax<Set<? extends Slice>> parser = (ParseSax<Set<? extends Slice>>) factory.create(injector
|
||||||
|
.getInstance(SlicesHandler.class));
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test() {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/test_get_slice.xml");
|
||||||
|
Set<? extends Slice> expects = ImmutableSet.of(new Slice(1, "jclouds-foo", 1, 10, null, Slice.Status.BUILD, 0, 0,
|
||||||
|
0, ImmutableSet.<String> of("174.143.212.229", "10.176.164.199"), null));
|
||||||
|
|
||||||
|
assertEquals(createParser().parse(is), expects);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2009 Cloud Conscious, LLC.
|
||||||
|
<info@cloudconscious.com>
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
|
||||||
|
applicable law or agreed to in writing, software distributed
|
||||||
|
under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions
|
||||||
|
and limitations under the License.
|
||||||
|
====================================================================
|
||||||
|
-->
|
||||||
|
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
For more configuration infromation and examples see the Apache
|
||||||
|
Log4j website: http://logging.apache.org/log4j/
|
||||||
|
-->
|
||||||
|
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||||
|
debug="false">
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-wire.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category]
|
||||||
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
|
</appender>
|
||||||
|
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- ================ -->
|
||||||
|
<!-- Limit categories -->
|
||||||
|
<!-- ================ -->
|
||||||
|
|
||||||
|
<category name="org.jclouds">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNC" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.headers">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
</category>
|
||||||
|
<category name="jclouds.wire">
|
||||||
|
<priority value="DEBUG" />
|
||||||
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
</category>
|
||||||
|
|
||||||
|
<category name="jclouds.compute">
|
||||||
|
<priority value="TRACE" />
|
||||||
|
<appender-ref ref="ASYNCCOMPUTE" />
|
||||||
|
</category>
|
||||||
|
<!-- ======================= -->
|
||||||
|
<!-- Setup the Root category -->
|
||||||
|
<!-- ======================= -->
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<priority value="WARN" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</log4j:configuration>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<errors>
|
||||||
|
<error>Slice parameters are not properly nested</error>
|
||||||
|
</errors>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<flavor>
|
||||||
|
<id type="integer">1</id>
|
||||||
|
<name>256 slice</name>
|
||||||
|
<price type="integer">2000</price>
|
||||||
|
<ram type="integer">256</ram>
|
||||||
|
</flavor>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<slices type="array">
|
||||||
|
<slice>
|
||||||
|
<name>jclouds-foo</name>
|
||||||
|
<image-id type="integer">10</image-id>
|
||||||
|
<addresses type="array">
|
||||||
|
<address>174.143.212.229</address>
|
||||||
|
<address>10.176.164.199</address>
|
||||||
|
</addresses>
|
||||||
|
<progress type="integer">0</progress>
|
||||||
|
<id type="integer">1</id>
|
||||||
|
<bw-out type="float">0.0</bw-out>
|
||||||
|
<bw-in type="float">0.0</bw-in>
|
||||||
|
<flavor-id type="integer">1</flavor-id>
|
||||||
|
<status>build</status>
|
||||||
|
<ip-address>174.143.212.229</ip-address>
|
||||||
|
</slice>
|
||||||
|
</slices>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<flavors type="array">
|
||||||
|
<flavor>
|
||||||
|
<id type="integer">1</id>
|
||||||
|
<name>256 slice</name>
|
||||||
|
<price type="integer">2000</price>
|
||||||
|
<ram type="integer">256</ram>
|
||||||
|
</flavor>
|
||||||
|
<flavor>
|
||||||
|
<id type="integer">2</id>
|
||||||
|
<name>512 slice</name>
|
||||||
|
<price type="integer">3800</price>
|
||||||
|
<ram type="integer">512</ram>
|
||||||
|
</flavor>
|
||||||
|
<flavor>
|
||||||
|
<id type="integer">3</id>
|
||||||
|
<name>1GB slice</name>
|
||||||
|
<price type="integer">7000</price>
|
||||||
|
<ram type="integer">1024</ram>
|
||||||
|
</flavor>
|
||||||
|
<flavor>
|
||||||
|
<id type="integer">4</id>
|
||||||
|
<name>2GB slice</name>
|
||||||
|
<price type="integer">13000</price>
|
||||||
|
<ram type="integer">2048</ram>
|
||||||
|
</flavor>
|
||||||
|
</flavors>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<images type="array">
|
||||||
|
<image>
|
||||||
|
<name>CentOS 5.2</name>
|
||||||
|
<id type="integer">2</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Gentoo 2008.0</name>
|
||||||
|
<id type="integer">3</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Debian 5.0 (lenny)</name>
|
||||||
|
<id type="integer">4</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Fedora 10 (Cambridge)</name>
|
||||||
|
<id type="integer">5</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>CentOS 5.3</name>
|
||||||
|
<id type="integer">7</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Ubuntu 9.04 (jaunty)</name>
|
||||||
|
<id type="integer">8</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Arch 2009.02</name>
|
||||||
|
<id type="integer">9</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Ubuntu 8.04.2 LTS (hardy)</name>
|
||||||
|
<id type="integer">10</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Ubuntu 8.10 (intrepid)</name>
|
||||||
|
<id type="integer">11</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Red Hat EL 5.3</name>
|
||||||
|
<id type="integer">12</id>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<name>Fedora 11 (Leonidas)</name>
|
||||||
|
<id type="integer">13</id>
|
||||||
|
</image>
|
||||||
|
</images>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<slice>
|
||||||
|
<name>slicetest</name>
|
||||||
|
<image-id type="integer">11</image-id>
|
||||||
|
<addresses type="array">
|
||||||
|
<address>10.176.168.15</address>
|
||||||
|
<address>67.23.20.114</address>
|
||||||
|
</addresses>
|
||||||
|
<root-password>fooadfa1231</root-password>
|
||||||
|
<progress type="integer">0</progress>
|
||||||
|
<id type="integer">71907</id>
|
||||||
|
<bw-out type="float">0.0</bw-out>
|
||||||
|
<bw-in type="float">0.0</bw-in>
|
||||||
|
<flavor-id type="integer">1</flavor-id>
|
||||||
|
<status>build</status>
|
||||||
|
<ip-address>10.176.168.15</ip-address>
|
||||||
|
</slice>
|
Loading…
Reference in New Issue