Issue 779:clean slate openstack nova skeleton

This commit is contained in:
Adrian Cole 2011-12-09 15:34:20 -08:00
parent a6d6b48c26
commit 0ca95e50eb
24 changed files with 1839 additions and 0 deletions

View File

@ -74,6 +74,9 @@ eucalyptus-partnercloud-ec2.propertiesbuilder=org.jclouds.epc.EucalyptusPartnerC
nova.contextbuilder=org.jclouds.openstack.nova.NovaContextBuilder
nova.propertiesbuilder=org.jclouds.openstack.nova.NovaPropertiesBuilder
openstack-nova.contextbuilder=org.jclouds.openstack.nova.v1_1.NovaContextBuilder
openstack-nova.propertiesbuilder=org.jclouds.openstack.nova.v1_1.NovaPropertiesBuilder
cloudservers.contextbuilder=org.jclouds.cloudservers.CloudServersContextBuilder
cloudservers.propertiesbuilder=org.jclouds.cloudservers.CloudServersPropertiesBuilder

View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<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.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.api</groupId>
<artifactId>openstack-nova</artifactId>
<name>jcloud openstack-nova api</name>
<description>jclouds components to access an implementation of OpenStack Nova</description>
<packaging>bundle</packaging>
<properties>
<test.openstack-nova.endpoint>http://localhost:8774/v1.1/</test.openstack-nova.endpoint>
<test.openstack-nova.apiversion>v1.1</test.openstack-nova.apiversion>
<test.openstack-nova.identity>FIXME_IDENTITY</test.openstack-nova.identity>
<test.openstack-nova.credential>FIXME_CREDENTIALS</test.openstack-nova.credential>
<test.openstack-nova.image-id></test.openstack-nova.image-id>
<test.openstack-nova.image.login-user></test.openstack-nova.image.login-user>
<test.openstack-nova.image.authenticate-sudo></test.openstack-nova.image.authenticate-sudo>
<test.ssh.keyfile.public></test.ssh.keyfile.public>
<test.ssh.keyfile.private></test.ssh.keyfile.private>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds.common</groupId>
<artifactId>openstack-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.common</groupId>
<artifactId>openstack-common</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-sshj</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
</dependency>
</dependencies>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemPropertyVariables>
<test.openstack-nova.endpoint>${test.openstack-nova.endpoint}</test.openstack-nova.endpoint>
<test.openstack-nova.apiversion>${test.openstack-nova.apiversion}</test.openstack-nova.apiversion>
<test.openstack-nova.identity>${test.openstack-nova.identity}</test.openstack-nova.identity>
<test.openstack-nova.credential>${test.openstack-nova.credential}</test.openstack-nova.credential>
<test.openstack-nova.image-id>${test.openstack-nova.image-id}</test.openstack-nova.image-id>
<test.openstack-nova.image.login-user>${test.openstack-nova.image.login-user}</test.openstack-nova.image.login-user>
<test.openstack-nova.image.authenticate-sudo>${test.openstack-nova.image.authenticate-sudo}</test.openstack-nova.image.authenticate-sudo>
<test.ssh.keyfile.public>${test.ssh.keyfile.public}</test.ssh.keyfile.public>
<test.ssh.keyfile.private>${test.ssh.keyfile.private}</test.ssh.keyfile.private>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jclouds.openstack.nova.v1_1.*;version="${project.version}"</Export-Package>
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,40 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
import org.jclouds.rest.annotations.Delegate;
/**
* Provides asynchronous access to Nova via their REST API.
* <p/>
*
* @see NovaClient
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
* @author Adrian Cole
*/
public interface NovaAsyncClient {
/**
* Provides asynchronous access to Server features.
*/
@Delegate
ServerAsyncClient getServerClient();
}

View File

@ -0,0 +1,44 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
import org.jclouds.rest.annotations.Delegate;
/**
* Provides synchronous access to Nova.
* <p/>
*
* @see NovaAsyncClient
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
* @author Adrian Cole
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface NovaClient {
/**
* Provides synchronous access to Server features.
*/
@Delegate
ServerClient getServerClient();
}

View File

@ -0,0 +1,44 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import java.util.List;
import java.util.Properties;
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class NovaContextBuilder extends RestContextBuilder<NovaClient, NovaAsyncClient> {
public NovaContextBuilder(Properties props) {
super(NovaClient.class, NovaAsyncClient.class, props);
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new NovaRestClientModule());
}
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import java.util.Properties;
import java.util.regex.Pattern;
import org.jclouds.PropertiesBuilder;
import org.jclouds.util.Strings2;
/**
* Builds properties used in Nova Clients
*
* @author Adrian Cole
*/
public class NovaPropertiesBuilder extends PropertiesBuilder {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8774/{apiversion}/{identity}");
properties.setProperty(PROPERTY_API_VERSION, "v1.1");
return properties;
}
public NovaPropertiesBuilder(Properties properties) {
super(properties);
}
public static final Pattern IDENTITY_PATTERN = Pattern.compile("\\{identity\\}");
public static final Pattern API_VERSION_PATTERN = Pattern.compile("\\{apiversion\\}");
@Override
public Properties build() {
// TODO determine if we can more elegantly do this. right now we have to
// because URI.create() doesn't allow us to build a URi with an illegal
// character '{'
String endpoint = properties.getProperty(PROPERTY_ENDPOINT);
String identity = properties.getProperty(PROPERTY_IDENTITY);
String apiVersion = properties.getProperty(PROPERTY_API_VERSION);
String withIdentity = Strings2.replaceAll(endpoint, IDENTITY_PATTERN, identity);
String withVersion = Strings2.replaceAll(withIdentity, API_VERSION_PATTERN, apiVersion);
properties.setProperty(PROPERTY_ENDPOINT, withVersion);
return super.build();
}
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.config;
import java.lang.reflect.Type;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.json.config.GsonModule;
import org.jclouds.json.config.GsonModule.DateAdapter;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* @author Adrian Cole
*/
public class NovaParserModule extends AbstractModule {
@Provides
@Singleton
public Map<Type, Object> provideCustomAdapterBindings() {
return ImmutableMap.<Type, Object>of(
);
}
@Override
protected void configure() {
bind(DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
}
}

View File

@ -0,0 +1,77 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.config;
import java.util.Map;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
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.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import com.google.common.collect.ImmutableMap;
/**
* Configures the Nova connection.
*
* @author Adrian Cole
*/
@RequiresHttp
@ConfiguresRestClient
public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(ServerClient.class, ServerAsyncClient.class)//
.build();
public NovaRestClientModule() {
super(NovaClient.class, NovaAsyncClient.class, DELEGATE_MAP);
}
@Override
protected void configure() {
install(new OpenStackAuthenticationModule());
install(new NovaParserModule());
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(NovaErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(NovaErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(NovaErrorHandler.class);
}
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(BackoffLimitedRetryHandler.class);
}
}

View File

@ -0,0 +1,160 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.gson.annotations.SerializedName;
/**
* Listing of a server.
*
* @author Adrian Cole
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/?a=doc#server_list" />
*/
public class Server {
public static Builder builder() {
return new Builder();
}
public static class Builder {
protected String id;
protected String hostname;
protected String datacenter;
protected String platform;
public Builder id(String id) {
this.id = id;
return this;
}
public Builder hostname(String hostname) {
this.hostname = hostname;
return this;
}
public Builder datacenter(String datacenter) {
this.datacenter = datacenter;
return this;
}
public Builder platform(String platform) {
this.platform = platform;
return this;
}
public Server build() {
return new Server(id, hostname, datacenter, platform);
}
public Builder fromServer(Server in) {
return datacenter(in.getDatacenter()).platform(in.getPlatform()).hostname(in.getHostname()).id(in.getId());
}
}
@SerializedName("serverid")
protected final String id;
protected final String hostname;
protected final String datacenter;
protected final String platform;
public Server(String id, String hostname, String datacenter, String platform) {
this.id = checkNotNull(id, "id");
this.hostname = checkNotNull(hostname, "hostname");
this.datacenter = checkNotNull(datacenter, "datacenter");
this.platform = checkNotNull(platform, "platform");
}
/**
* @return the generated id of the server
*/
public String getId() {
return id;
}
/**
* @return the hostname of the server
*/
public String getHostname() {
return hostname;
}
/**
* @return platform running the server (ex. {@code OpenVZ})
*/
public String getPlatform() {
return platform;
}
/**
* @return the datacenter the server exists in (ex. {@code Falkenberg})
*/
public String getDatacenter() {
return datacenter;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((datacenter == null) ? 0 : datacenter.hashCode());
result = prime * result + ((hostname == null) ? 0 : hostname.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((platform == null) ? 0 : platform.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;
Server other = (Server) obj;
if (datacenter == null) {
if (other.datacenter != null)
return false;
} else if (!datacenter.equals(other.datacenter))
return false;
if (hostname == null) {
if (other.hostname != null)
return false;
} else if (!hostname.equals(other.hostname))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (platform == null) {
if (other.platform != null)
return false;
} else if (!platform.equals(other.platform))
return false;
return true;
}
@Override
public String toString() {
return String.format("[id=%s, hostname=%s, datacenter=%s, platform=%s]", id, hostname, datacenter, platform);
}
}

View File

@ -0,0 +1,150 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.gson.annotations.SerializedName;
/**
* Detailed information about a server such as cpuCores, hardware configuration
* (cpu, memory and disk), ip adresses, cost, transfer, os and more.
*
* @author Adrian Cole
* @see <a href=
* "http://docs.openstack.org/api/openstack-compute/1.1/content/?a=doc#server_details"
* />
*/
public class ServerDetails extends Server {
public static Builder builder() {
return new Builder();
}
public static class Builder extends Server.Builder {
private String description;
private int cpuCores;
private int memory;
private int disk;
public Builder description(String description) {
this.description = description;
return this;
}
public Builder cpuCores(int cpuCores) {
this.cpuCores = cpuCores;
return this;
}
public Builder memory(int memory) {
this.memory = memory;
return this;
}
public Builder disk(int disk) {
this.disk = disk;
return this;
}
public ServerDetails build() {
return new ServerDetails(id, hostname, datacenter, platform, description, cpuCores, memory, disk);
}
public Builder fromServerDetails(ServerDetails in) {
return fromServer(in).memory(in.getMemory()).disk(in.getDisk()).cpuCores(in.getCpuCores())
.description(in.getDescription());
}
@Override
public Builder id(String id) {
return Builder.class.cast(super.id(id));
}
@Override
public Builder hostname(String hostname) {
return Builder.class.cast(super.hostname(hostname));
}
@Override
public Builder datacenter(String datacenter) {
return Builder.class.cast(super.datacenter(datacenter));
}
@Override
public Builder platform(String platform) {
return Builder.class.cast(super.platform(platform));
}
@Override
public Builder fromServer(Server in) {
return Builder.class.cast(super.fromServer(in));
}
}
private final String description;
@SerializedName("cpucores")
private final int cpuCores;
private final int memory;
private final int disk;
public ServerDetails(String id, String hostname, String datacenter, String platform, String description,
int cpuCores, int memory, int disk) {
super(id, hostname, datacenter, platform);
this.description = checkNotNull(description, "description");
this.cpuCores = cpuCores;
this.memory = memory;
this.disk = disk;
}
/**
* @return the user-specified description of the server
*/
public String getDescription() {
return description;
}
/**
* @return number of cores on the server
*/
public int getCpuCores() {
return cpuCores;
}
/**
* @return the disk of the server in GB
*/
public int getDisk() {
return disk;
}
/**
* @return the memory of the server in MB
*/
public int getMemory() {
return memory;
}
@Override
public String toString() {
return String.format(
"[id=%s, hostname=%s, datacenter=%s, platform=%s, description=%s, cpuCores=%s, memory=%s, disk=%s]", id,
hostname, datacenter, platform, description, cpuCores, memory, disk);
}
}

View File

@ -0,0 +1,71 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Server via their REST API.
* <p/>
*
* @see ServerClient
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
* @author Adrian Cole
*/
@RequestFilters(AuthenticateRequest.class)
public interface ServerAsyncClient {
/**
* @see ServerClient#listServers
*/
@GET
@SelectJson("servers")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/servers")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Server>> listServers();
/**
* @see ServerClient#getServerDetails
*/
@GET
@SelectJson("server")
@Consumes(MediaType.APPLICATION_JSON)
@Path("/servers/{id}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<ServerDetails> getServerDetails(@PathParam("id") String id);
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
/**
* Provides synchronous access to Server.
* <p/>
*
* @see ServerAsyncClient
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
* @author Adrian Cole
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface ServerClient {
/**
* Get a list of all servers on this account.
*
* @return an account's associated server objects.
*/
Set<Server> listServers();
/**
* Get detailed information about a server such as hostname, hardware
* configuration (cpu, memory and disk), ip adresses, cost, transfer, os and
* more.
*
* @param id
* id of the server
* @return server or null if not found
*/
ServerDetails getServerDetails(String id);
}

View File

@ -0,0 +1,90 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.handlers;
import java.io.IOException;
import javax.inject.Singleton;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
@Singleton
public class NovaErrorHandler implements HttpErrorHandler {
public void handleError(HttpCommand command, HttpResponse response) {
// it is important to always read fully and close streams
String message = parseMessage(response);
Exception exception = message != null ? new HttpResponseException(command, response, message)
: new HttpResponseException(command, response);
try {
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
response.getStatusLine());
switch (response.getStatusCode()) {
case 401:
case 403:
exception = new AuthorizationException(message, exception);
break;
case 404:
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
exception = new ResourceNotFoundException(message, exception);
}
break;
case 500:
if (message != null && message.indexOf("Unable to determine package for") != -1) {
exception = new ResourceNotFoundException(message, exception);
}
}
} finally {
if (response.getPayload() != null)
Closeables.closeQuietly(response.getPayload().getInput());
command.setException(exception);
}
}
public String parseMessage(HttpResponse response) {
if (response.getPayload() == null)
return null;
try {
return Strings2.toStringAndClose(response.getPayload().getInput());
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
response.getPayload().getInput().close();
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
}

View File

@ -0,0 +1,71 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.nova.v1_1.features.BaseNovaAsyncClientTest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code NovaAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@Test(groups = "unit", testName = "NovaAsyncClientTest")
public class NovaAsyncClientTest extends BaseNovaAsyncClientTest<NovaAsyncClient> {
private NovaAsyncClient asyncClient;
private NovaClient syncClient;
public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert syncClient.getServerClient() != null;
}
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert asyncClient.getServerClient() != null;
}
@Override
protected TypeLiteral<RestAnnotationProcessor<NovaAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<NovaAsyncClient>>() {
};
}
@BeforeClass
@Override
protected void setupFactory() throws IOException {
super.setupFactory();
asyncClient = injector.getInstance(NovaAsyncClient.class);
syncClient = injector.getInstance(NovaClient.class);
}
@Override
protected void checkFilters(HttpRequest request) {
}
}

View File

@ -0,0 +1,117 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import org.easymock.IArgumentMatcher;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.inject.Guice;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class NovaErrorHandlerTest {
@Test
public void test500MakesResourceNotFoundExceptionOnUnableToDeterminePackage() {
assertCodeMakes(
"GET",
URI.create("https://api.openstack.nova.v1_1.com/foo"),
500,
"",
"{\"error\":\"Unable to determine package for 'node2102835255.me.org'.\"}",
ResourceNotFoundException.class);
}
@Test
public void test401MakesAuthorizationException() {
assertCodeMakes("GET", URI.create("https://api.openstack.nova.v1_1.com/foo"), 401, "", "Unauthorized",
AuthorizationException.class);
}
@Test
public void test404MakesResourceNotFoundException() {
assertCodeMakes("GET", URI.create("https://api.openstack.nova.v1_1.com/foo"), 404, "", "Not Found",
ResourceNotFoundException.class);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
Class<? extends Exception> expected) {
assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
NovaErrorHandler function = Guice.createInjector().getInstance(NovaErrorHandler.class);
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2
.toInputStream(content)));
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {
@Override
public void appendTo(StringBuffer buffer) {
buffer.append("classEq(");
buffer.append(in);
buffer.append(")");
}
@Override
public boolean matches(Object arg) {
return arg.getClass() == in;
}
});
return null;
}
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import static org.testng.Assert.assertEquals;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.openstack.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
/**
* @author Adrian Cole
*/
public abstract class BaseNovaAsyncClientTest<T> extends RestClientTest<T> {
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), AuthenticateRequest.class);
}
@Override
public RestContextSpec<NovaClient, NovaAsyncClient> createContextSpec() {
Properties props = new Properties();
return new RestContextFactory().createContextSpec("openstack-nova", "accountId", "accessKey", props);
}
}

View File

@ -0,0 +1,62 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
import org.jclouds.openstack.nova.v1_1.NovaClient;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* Tests behavior of {@code NovaClient}
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseNovaClientLiveTest {
protected RestContext<NovaClient, NovaAsyncClient> context;
@BeforeGroups(groups = { "live" })
public void setupClient() {
String identity = checkNotNull(System.getProperty("test.openstack.nova.v1_1.identity"), "test.openstack.nova.v1_1.identity");
String credential = checkNotNull(System.getProperty("test.openstack.nova.v1_1.credential"), "test.openstack.nova.v1_1.credential");
context = new RestContextFactory().createContext("openstack-nova", identity, credential,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
}
@AfterGroups(groups = "live")
protected void tearDown() {
if (context != null)
context.close();
}
}

View File

@ -0,0 +1,79 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code ServerAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ServerAsyncClientTest")
public class ServerAsyncClientTest extends BaseNovaAsyncClientTest<ServerAsyncClient> {
public void testListServers() throws SecurityException, NoSuchMethodException, IOException {
Method method = ServerAsyncClient.class.getMethod("listServers");
HttpRequest httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, "GET http://localhost:8774/v1.1/accountId/servers HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetServer() throws SecurityException, NoSuchMethodException, IOException {
Method method = ServerAsyncClient.class.getMethod("getServerDetails", String.class);
HttpRequest httpRequest = processor.createRequest(method, "abcd");
assertRequestLineEquals(httpRequest,
"GET http://localhost:8774/v1.1/accountId/servers/abcd HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseFirstJsonValueNamed.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<ServerAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<ServerAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,68 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code ServerClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "ServerClientLiveTest")
public class ServerClientLiveTest extends BaseNovaClientLiveTest {
@BeforeGroups(groups = {"live"})
public void setupClient() {
super.setupClient();
client = context.getApi().getServerClient();
}
private ServerClient client;
@Test
public void testListServers() throws Exception {
Set<Server> response = client.listServers();
assert null != response;
assertTrue(response.size() >= 0);
for (Server server : response) {
ServerDetails newDetails = client.getServerDetails(server.getId());
assertEquals(newDetails.getId(), server.getId());
assertEquals(newDetails.getHostname(), server.getHostname());
assertEquals(newDetails.getPlatform(), server.getPlatform());
assertEquals(newDetails.getDatacenter(), server.getDatacenter());
checkServer(newDetails);
}
}
private void checkServer(ServerDetails server) {
// description can be null
assert server.getCpuCores() > 0 : server;
assert server.getDisk() > 0 : server;
assert server.getMemory() > 0 : server;
}
}

View File

@ -0,0 +1,58 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.parse;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseServerDetailsTest")
public class ParseServerDetailsTest extends BaseItemParserTest<ServerDetails> {
@Override
public String resource() {
return "/server.json";
}
@Override
@SelectJson("server")
@Consumes(MediaType.APPLICATION_JSON)
public ServerDetails expected() {
return ServerDetails.builder().id("vz1541880").hostname("mammamia").datacenter("Falkenberg").platform("OpenVZ")
.description("description").cpuCores(1).memory(128).disk(5).build();
}
protected Injector injector() {
return Guice.createInjector(new NovaParserModule(), new GsonModule());
}
}

View File

@ -0,0 +1,61 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.openstack.nova.v1_1.parse;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
import org.jclouds.openstack.nova.v1_1.domain.Server;
import org.jclouds.rest.annotations.SelectJson;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseServerListTest")
public class ParseServerListTest extends BaseSetParserTest<Server> {
@Override
public String resource() {
return "/server_list.json";
}
@Override
@SelectJson("servers")
@Consumes(MediaType.APPLICATION_JSON)
public Set<Server> expected() {
return ImmutableSet.of(Server.builder().id("vz1541880").hostname("mammamia").datacenter("Falkenberg")
.platform("OpenVZ").build());
}
protected Injector injector() {
return Guice.createInjector(new NovaParserModule(), new GsonModule());
}
}

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.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="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</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.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</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>

View File

@ -0,0 +1,54 @@
{
"server": {
"status": "REBOOT",
"updated": "2011-12-06T22:37:44Z",
"hostId": "3852db942cbeb5e840d759de11bdef403e2a0149c66f06a5d7caa61e",
"user_id": "dev_41247879706381",
"name": "jd-test-tiny",
"links": [
{
"href": "http://se1.devex.me:8774/v1.1/dev_16767499955063/servers/804",
"rel": "self"
},
{
"href": "http://se1.devex.me:8774/dev_16767499955063/servers/804",
"rel": "bookmark"
}
],
"addresses": {
"novanet_7": [
{
"version": 4,
"addr": "10.0.0.229"
}
]
},
"tenant_id": "dev_16767499955063",
"image": {
"id": "146",
"links": [
{
"href": "http://se1.devex.me:8774/dev_16767499955063/images/146",
"rel": "bookmark"
}
]
},
"created": "2011-12-02T16:04:54Z",
"uuid": "0bab236f-f5c4-46ef-93c2-a8e2bcfffff6",
"accessIPv4": "",
"accessIPv6": "",
"key_name": null,
"flavor": {
"id": "1",
"links": [
{
"href": "http://se1.devex.me:8774/dev_16767499955063/flavors/1",
"rel": "bookmark"
}
]
},
"config_drive": "",
"id": 804,
"metadata": {}
}
}

View File

@ -0,0 +1,64 @@
{
"servers": [
{
"uuid": "0bab236f-f5c4-46ef-93c2-a8e2bcfffff6",
"name": "jd-test-tiny",
"links": [
{
"href": "http://se1.devex.me:8774/v1.1/dev_16767499955063/servers/804",
"rel": "self"
},
{
"href": "http://se1.devex.me:8774/dev_16767499955063/servers/804",
"rel": "bookmark"
}
],
"id": 804
},
{
"uuid": "488eac65-84ab-4f10-b2a4-555c23613428",
"name": "rgtest2",
"links": [
{
"href": "http://se1.devex.me:8774/v1.1/dev_16767499955063/servers/528",
"rel": "self"
},
{
"href": "http://se1.devex.me:8774/dev_16767499955063/servers/528",
"rel": "bookmark"
}
],
"id": 528
},
{
"uuid": "df891742-4ecb-4f9f-b206-b2a4d821a100",
"name": "rgtest",
"links": [
{
"href": "http://se1.devex.me:8774/v1.1/dev_16767499955063/servers/507",
"rel": "self"
},
{
"href": "http://se1.devex.me:8774/dev_16767499955063/servers/507",
"rel": "bookmark"
}
],
"id": 507
},
{
"uuid": "42cded93-1ade-4da2-b39f-70e6577c2b82",
"name": "fog_hprgmac.local_1320358100_server",
"links": [
{
"href": "http://se1.devex.me:8774/v1.1/dev_16767499955063/servers/430",
"rel": "self"
},
{
"href": "http://se1.devex.me:8774/dev_16767499955063/servers/430",
"rel": "bookmark"
}
],
"id": 430
}
]
}