mirror of https://github.com/apache/jclouds.git
Issue 814:move openstack-nova to org.jclouds.labs groupId
This commit is contained in:
parent
55c12680a3
commit
de720b6da3
|
@ -27,23 +27,23 @@
|
||||||
<version>1.4.0-SNAPSHOT</version>
|
<version>1.4.0-SNAPSHOT</version>
|
||||||
<relativePath>../../project/pom.xml</relativePath>
|
<relativePath>../../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.jclouds.api</groupId>
|
<groupId>org.jclouds.labs</groupId>
|
||||||
<artifactId>openstack-nova</artifactId>
|
<artifactId>openstack-nova</artifactId>
|
||||||
<name>jcloud openstack-nova api</name>
|
<name>jcloud openstack-nova api</name>
|
||||||
<description>jclouds components to access an implementation of OpenStack Nova</description>
|
<description>jclouds components to access an implementation of OpenStack Nova</description>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<test.openstack-nova.endpoint>http://localhost:8774/v1.1/</test.openstack-nova.endpoint>
|
<!-- keystone endpoint -->
|
||||||
<test.openstack-nova.api-version>v1.1</test.openstack-nova.api-version>
|
<test.openstack-nova.endpoint>http://localhost:5000</test.openstack-nova.endpoint>
|
||||||
|
<!-- keystone version -->
|
||||||
|
<test.openstack-nova.api-version>1.1</test.openstack-nova.api-version>
|
||||||
<test.openstack-nova.build-version></test.openstack-nova.build-version>
|
<test.openstack-nova.build-version></test.openstack-nova.build-version>
|
||||||
<test.openstack-nova.identity>FIXME_IDENTITY</test.openstack-nova.identity>
|
<test.openstack-nova.identity>FIXME_IDENTITY</test.openstack-nova.identity>
|
||||||
<test.openstack-nova.credential>FIXME_CREDENTIALS</test.openstack-nova.credential>
|
<test.openstack-nova.credential>FIXME_CREDENTIALS</test.openstack-nova.credential>
|
||||||
<test.openstack-nova.image-id></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.login-user>
|
||||||
<test.openstack-nova.image.authenticate-sudo></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.private></test.ssh.keyfile.private>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -86,10 +86,16 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jclouds.driver</groupId>
|
<groupId>org.jclouds.driver</groupId>
|
||||||
<artifactId>jclouds-log4j</artifactId>
|
<artifactId>jclouds-slf4j</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>0.9.29</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
|
@ -100,12 +106,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.maven.surefire</groupId>
|
|
||||||
<artifactId>surefire-testng</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>integration</id>
|
<id>integration</id>
|
||||||
|
@ -123,8 +123,6 @@
|
||||||
<test.openstack-nova.image-id>${test.openstack-nova.image-id}</test.openstack-nova.image-id>
|
<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.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.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>
|
</systemPropertyVariables>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
@ -144,7 +142,12 @@
|
||||||
<instructions>
|
<instructions>
|
||||||
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
|
||||||
<Export-Package>org.jclouds.openstack.nova.v1_1.*;version="${project.version}"</Export-Package>
|
<Export-Package>org.jclouds.openstack.nova.v1_1.*;version="${project.version}"</Export-Package>
|
||||||
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
|
<Import-Package>
|
||||||
|
org.jclouds.compute.internal;version="${project.version}",
|
||||||
|
org.jclouds.rest.internal;version="${project.version}",
|
||||||
|
org.jclouds.*;version="${project.version}",
|
||||||
|
*
|
||||||
|
</Import-Package>
|
||||||
</instructions>
|
</instructions>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* 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.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see <a href="http://docs.openstack.org/incubation/identity-dev-guide/content/Authenticate-Service-API-d1e1166.html"
|
||||||
|
* />
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||||
|
@Qualifier
|
||||||
|
public @interface Compute {
|
||||||
|
|
||||||
|
}
|
|
@ -20,13 +20,10 @@ package org.jclouds.openstack.nova.v1_1;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import org.jclouds.PropertiesBuilder;
|
||||||
import org.jclouds.util.Strings2;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds properties used in Nova Clients
|
* Builds properties used in Nova Clients
|
||||||
|
@ -37,8 +34,9 @@ public class NovaPropertiesBuilder extends PropertiesBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:8774/{api-version}/{identity}");
|
// TODO: keystone
|
||||||
properties.setProperty(PROPERTY_API_VERSION, "v1.1");
|
properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:5000");
|
||||||
|
properties.setProperty(PROPERTY_API_VERSION, "1.1");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,20 +44,4 @@ public class NovaPropertiesBuilder extends PropertiesBuilder {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Pattern IDENTITY_PATTERN = Pattern.compile("\\{identity\\}");
|
|
||||||
public static final Pattern API_VERSION_PATTERN = Pattern.compile("\\{api-version\\}");
|
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -18,8 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1.config;
|
package org.jclouds.openstack.nova.v1_1.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.HttpRetryHandler;
|
import org.jclouds.http.HttpRetryHandler;
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
@ -27,16 +30,20 @@ import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||||
|
import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse;
|
||||||
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
|
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.Compute;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.ServerAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
|
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
|
||||||
|
import org.jclouds.openstack.reference.AuthHeaders;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the Nova connection.
|
* Configures the Nova connection.
|
||||||
|
@ -48,16 +55,23 @@ import com.google.common.collect.ImmutableMap;
|
||||||
public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsyncClient> {
|
public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsyncClient> {
|
||||||
|
|
||||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
|
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
|
||||||
.put(ServerClient.class, ServerAsyncClient.class)//
|
.put(ServerClient.class, ServerAsyncClient.class)//
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
private final OpenStackAuthenticationModule authModule;
|
||||||
|
|
||||||
public NovaRestClientModule() {
|
public NovaRestClientModule() {
|
||||||
|
this(new OpenStackAuthenticationModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
public NovaRestClientModule(OpenStackAuthenticationModule authModule) {
|
||||||
super(NovaClient.class, NovaAsyncClient.class, DELEGATE_MAP);
|
super(NovaClient.class, NovaAsyncClient.class, DELEGATE_MAP);
|
||||||
|
this.authModule = authModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new OpenStackAuthenticationModule());
|
install(authModule);
|
||||||
install(new NovaParserModule());
|
install(new NovaParserModule());
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
@ -74,4 +88,13 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
||||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(BackoffLimitedRetryHandler.class);
|
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(BackoffLimitedRetryHandler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: get this from Keystone!!
|
||||||
|
// http://docs.openstack.org/incubation/identity-dev-guide/content/Authenticate-Service-API-d1e1166.html
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Compute
|
||||||
|
protected URI provideServerUrl(AuthenticationResponse response) {
|
||||||
|
return response.getServices().get(AuthHeaders.SERVER_MANAGEMENT_URL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
/**
|
||||||
|
* 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.Objects.equal;
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP address
|
||||||
|
*
|
||||||
|
* @author AdrianCole
|
||||||
|
*/
|
||||||
|
public class Address {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relations associated with resources.
|
||||||
|
*/
|
||||||
|
public static enum Type {
|
||||||
|
/**
|
||||||
|
* publically routable address
|
||||||
|
*/
|
||||||
|
PUBLIC,
|
||||||
|
/**
|
||||||
|
* address that is not publicly routable.
|
||||||
|
*/
|
||||||
|
PRIVATE,
|
||||||
|
/**
|
||||||
|
* the value returned by the OpenStack service was not recognized.
|
||||||
|
*/
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type fromValue(String v) {
|
||||||
|
try {
|
||||||
|
return valueOf(v.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromAddress(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Address createV4(String addr) {
|
||||||
|
return builder().version(4).addr(addr).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Address createV6(String addr) {
|
||||||
|
return builder().version(6).addr(addr).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected String addr;
|
||||||
|
protected int version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Address#getVersion()
|
||||||
|
*/
|
||||||
|
protected Builder version(int version) {
|
||||||
|
this.version = version;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Address#getAddr()
|
||||||
|
*/
|
||||||
|
public Builder addr(String addr) {
|
||||||
|
this.addr = addr;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Address build() {
|
||||||
|
return new Address(addr, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromAddress(Address from) {
|
||||||
|
return addr(from.getAddr()).version(from.getVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String addr;
|
||||||
|
protected final int version;
|
||||||
|
|
||||||
|
public Address(String addr, int version) {
|
||||||
|
this.addr = addr;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ip address
|
||||||
|
*/
|
||||||
|
public String getAddr() {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the IP version, ex. 4
|
||||||
|
*/
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (object instanceof Address) {
|
||||||
|
final Address other = Address.class.cast(object);
|
||||||
|
return equal(addr, other.addr) && equal(version, other.version);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(addr, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper("").add("addr", addr).add("version", version).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,168 @@
|
||||||
|
/**
|
||||||
|
* 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, Href 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.Objects.equal;
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For convenience, resources contain links to themselves. This allows a client to easily obtain a
|
||||||
|
* resource URIs rather than to construct them.
|
||||||
|
*
|
||||||
|
* @author AdrianCole
|
||||||
|
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/LinksReferences.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class Link {
|
||||||
|
/**
|
||||||
|
* Relations associated with resources.
|
||||||
|
*/
|
||||||
|
public static enum Relation {
|
||||||
|
/**
|
||||||
|
* a versioned link to the resource. These links should be used in cases where the link will
|
||||||
|
* be followed immediately.
|
||||||
|
*/
|
||||||
|
SELF,
|
||||||
|
/**
|
||||||
|
* a permanent link to a resource that is appropriate for long term storage.
|
||||||
|
*/
|
||||||
|
BOOKMARK,
|
||||||
|
/**
|
||||||
|
* an alternate representation of the resource. For example, an OpenStack Compute image may
|
||||||
|
* have an alternate representation in the OpenStack Image service.
|
||||||
|
*/
|
||||||
|
ALTERNATE,
|
||||||
|
/**
|
||||||
|
* the value returned by the OpenStack service was not recognized.
|
||||||
|
*/
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
public String value() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Relation fromValue(String v) {
|
||||||
|
try {
|
||||||
|
return valueOf(v.toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Link create(Relation relation, URI href) {
|
||||||
|
return new Link(relation, href);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromLink(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected Relation relation;
|
||||||
|
protected URI href;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Link#getRelation()
|
||||||
|
*/
|
||||||
|
public Builder relation(Relation relation) {
|
||||||
|
this.relation = checkNotNull(relation, "relation");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Link#getHref()
|
||||||
|
*/
|
||||||
|
protected Builder href(URI href) {
|
||||||
|
this.href = checkNotNull(href, "href");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromLink(Link from) {
|
||||||
|
return relation(from.getRelation()).href(from.getHref());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SerializedName("rel")
|
||||||
|
protected final Relation relation;
|
||||||
|
protected final URI href;
|
||||||
|
|
||||||
|
protected Link(Relation relation, URI href) {
|
||||||
|
this.relation = checkNotNull(relation, "relation");
|
||||||
|
this.href = checkNotNull(href, "href");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There are three kinds of link relations associated with resources. A self link contains a
|
||||||
|
* versioned link to the resource. These links should be used in cases where the link will be
|
||||||
|
* followed immediately. A bookmark link provides a permanent link to a resource that is
|
||||||
|
* appropriate for long term storage. An alternate link can contain an alternate representation
|
||||||
|
* of the resource. For example, an OpenStack Compute image may have an alternate representation
|
||||||
|
* in the OpenStack Image service. Note that the type attribute here is used to provide a hint as
|
||||||
|
* to the type of representation to expect when following the link.
|
||||||
|
*
|
||||||
|
* @return the relation of the resource in the current OpenStack deployment
|
||||||
|
*/
|
||||||
|
public Relation getRelation() {
|
||||||
|
return relation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the href of the resource
|
||||||
|
*/
|
||||||
|
public URI getHref() {
|
||||||
|
return href;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (object instanceof Link) {
|
||||||
|
final Link other = Link.class.cast(object);
|
||||||
|
return equal(relation, other.relation) && equal(href, other.href);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(relation, href);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper("").add("relation", relation).add("href", href).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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, Name 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.Objects.equal;
|
||||||
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource found in a paginated collection
|
||||||
|
*
|
||||||
|
* @author AdrianCole
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Paginated_Collections-d1e664.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class Resource implements Comparable<Resource> {
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromResource(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
protected String id;
|
||||||
|
protected String name;
|
||||||
|
protected Set<Link> links = ImmutableSet.of();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Resource#getId()
|
||||||
|
*/
|
||||||
|
public Builder id(String id) {
|
||||||
|
this.id = checkNotNull(id, "id");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Resource#getName()
|
||||||
|
*/
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = checkNotNull(name, "name");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Resource#getLinks()
|
||||||
|
*/
|
||||||
|
public Builder links(Link... links) {
|
||||||
|
return links(ImmutableSet.copyOf(checkNotNull(links, "links")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Resource#getLinks()
|
||||||
|
*/
|
||||||
|
public Builder links(Set<Link> links) {
|
||||||
|
this.links = ImmutableSet.copyOf(checkNotNull(links, "links"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource build() {
|
||||||
|
return new Resource(id, name, links);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromResource(Resource from) {
|
||||||
|
return id(from.getId()).name(from.getName()).links(from.getLinks());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String id;
|
||||||
|
protected final String name;
|
||||||
|
protected final Set<Link> links;
|
||||||
|
|
||||||
|
public Resource(String id, String name, Set<Link> links) {
|
||||||
|
this.id = checkNotNull(id, "id");
|
||||||
|
this.name = checkNotNull(name, "name");
|
||||||
|
this.links = ImmutableSet.copyOf(checkNotNull(links, "links"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When providing an ID, it is assumed that the resource exists in the current OpenStack
|
||||||
|
* deployment
|
||||||
|
*
|
||||||
|
* @return the id of the resource in the current OpenStack deployment
|
||||||
|
*/
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the name of the resource
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the links of the id address allocated to the new server
|
||||||
|
*/
|
||||||
|
public Set<Link> getLinks() {
|
||||||
|
return links;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (object instanceof Resource) {
|
||||||
|
final Resource other = Resource.class.cast(object);
|
||||||
|
return equal(id, other.id) && equal(name, other.name) && equal(links, other.links);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(id, name, links);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper("").add("id", id).add("name", name).add("links", links).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Resource that) {
|
||||||
|
if (that == null)
|
||||||
|
return 1;
|
||||||
|
if (this == that)
|
||||||
|
return 0;
|
||||||
|
return this.id.compareTo(that.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
/**
|
||||||
|
* 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.Objects.toStringHelper;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Address.Type;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.util.NovaUtils;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.LinkedHashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A server is a virtual machine instance in the compute system. Flavor and image are requisite
|
||||||
|
* elements when creating a server.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Get_Server_Details-d1e2623.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class Server extends Resource {
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder toBuilder() {
|
||||||
|
return builder().fromServer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder extends Resource.Builder {
|
||||||
|
private Multimap<Address.Type, Address> addresses = LinkedHashMultimap.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Server#getAddresses()
|
||||||
|
*/
|
||||||
|
public Builder addresses(Multimap<Address.Type, Address> addresses) {
|
||||||
|
this.addresses = ImmutableMultimap.copyOf(checkNotNull(addresses, "addresses"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Server#getPrivateAddresses()
|
||||||
|
*/
|
||||||
|
public Builder privateAddresses(Address... privateAddresses) {
|
||||||
|
return privateAddresses(ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Server#getPrivateAddresses()
|
||||||
|
*/
|
||||||
|
public Builder privateAddresses(Set<Address> privateAddresses) {
|
||||||
|
this.addresses.replaceValues(Address.Type.PRIVATE, ImmutableSet.copyOf(checkNotNull(privateAddresses,
|
||||||
|
"privateAddresses")));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Server#getPublicAddresses()
|
||||||
|
*/
|
||||||
|
public Builder publicAddresses(Address... publicAddresses) {
|
||||||
|
return publicAddresses(ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Server#getPublicAddresses()
|
||||||
|
*/
|
||||||
|
public Builder publicAddresses(Set<Address> publicAddresses) {
|
||||||
|
this.addresses.replaceValues(Address.Type.PUBLIC, ImmutableSet.copyOf(checkNotNull(publicAddresses,
|
||||||
|
"publicAddresses")));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Server build() {
|
||||||
|
return new Server(id, name, links, addresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromServer(Server in) {
|
||||||
|
return fromResource(in).addresses(in.getAddresses());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder id(String id) {
|
||||||
|
return Builder.class.cast(super.id(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder name(String name) {
|
||||||
|
return Builder.class.cast(super.name(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder links(Set<Link> links) {
|
||||||
|
return Builder.class.cast(super.links(links));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder fromResource(Resource in) {
|
||||||
|
return Builder.class.cast(super.fromResource(in));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: get gson multimap adapter!
|
||||||
|
protected final Map<Address.Type, Set<Address>> addresses;
|
||||||
|
|
||||||
|
protected Server(String id, String name, Set<Link> links, Multimap<Address.Type, Address> addresses) {
|
||||||
|
super(id, name, links);
|
||||||
|
this.addresses = NovaUtils.toOldSchool(ImmutableMultimap.copyOf(checkNotNull(addresses, "addresses")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the private ip addresses assigned to the server
|
||||||
|
*/
|
||||||
|
public Set<Address> getPrivateAddresses() {
|
||||||
|
return ImmutableSet.copyOf(addresses.get(Address.Type.PRIVATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the public ip addresses assigned to the server
|
||||||
|
*/
|
||||||
|
public Set<Address> getPublicAddresses() {
|
||||||
|
return ImmutableSet.copyOf(addresses.get(Address.Type.PUBLIC));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the ip addresses assigned to the server
|
||||||
|
*/
|
||||||
|
public Multimap<Type, Address> getAddresses() {
|
||||||
|
return NovaUtils.fromOldSchool(addresses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return toStringHelper("").add("id", id).add("name", name).add("links", links).add("addresses", addresses)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,11 +27,14 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.openstack.filters.AuthenticateRequest;
|
import org.jclouds.openstack.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.Compute;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Resource;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
|
import org.jclouds.rest.annotations.Endpoint;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
@ -42,10 +45,13 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @see ServerClient
|
* @see ServerClient
|
||||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/Servers-d1e2073.html"
|
||||||
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@Endpoint(Compute.class)
|
||||||
public interface ServerAsyncClient {
|
public interface ServerAsyncClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,16 +62,26 @@ public interface ServerAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/servers")
|
@Path("/servers")
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<Set<Server>> listServers();
|
ListenableFuture<Set<Resource>> listServers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ServerClient#getServerDetails
|
* @see ServerClient#listServersInDetail
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@SelectJson("servers")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/servers/detail")
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Server>> listServersInDetail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ServerClient#getServer
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@SelectJson("server")
|
@SelectJson("server")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
ListenableFuture<ServerDetails> getServerDetails(@PathParam("id") String id);
|
ListenableFuture<Server> getServer(@PathParam("id") String id);
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,37 +22,42 @@ import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Resource;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides synchronous access to Server.
|
* Provides synchronous access to Server.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @see ServerAsyncClient
|
* @see ServerAsyncClient
|
||||||
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/" />
|
* @see <a href="http://docs.openstack.org/api/openstack-compute/1.1/content/Servers-d1e2073.html"
|
||||||
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
public interface ServerClient {
|
public interface ServerClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of all servers on this account.
|
* List all servers (IDs, names, links)
|
||||||
*
|
*
|
||||||
* @return an account's associated server objects.
|
* @return all servers (IDs, names, links)
|
||||||
*/
|
*/
|
||||||
Set<Server> listServers();
|
Set<Resource> listServers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get detailed information about a server such as hostname, hardware
|
* List all servers (all details)
|
||||||
* configuration (cpu, memory and disk), ip adresses, cost, transfer, os and
|
*
|
||||||
* more.
|
* @return all servers (all details)
|
||||||
|
*/
|
||||||
|
Set<Server> listServersInDetail();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List details of the specified server
|
||||||
*
|
*
|
||||||
* @param id
|
* @param id
|
||||||
* id of the server
|
* id of the server
|
||||||
* @return server or null if not found
|
* @return server or null if not found
|
||||||
*/
|
*/
|
||||||
ServerDetails getServerDetails(String id);
|
Server getServer(String id);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1.handlers;
|
package org.jclouds.openstack.nova.v1_1.handlers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
@ -28,10 +28,6 @@ import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
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.
|
* This will parse and set an appropriate exception on the command object.
|
||||||
|
@ -44,47 +40,28 @@ public class NovaErrorHandler implements HttpErrorHandler {
|
||||||
|
|
||||||
public void handleError(HttpCommand command, HttpResponse response) {
|
public void handleError(HttpCommand command, HttpResponse response) {
|
||||||
// it is important to always read fully and close streams
|
// it is important to always read fully and close streams
|
||||||
String message = parseMessage(response);
|
byte[] data = closeClientButKeepContentStream(response);
|
||||||
|
String message = data != null ? new String(data) : null;
|
||||||
|
|
||||||
Exception exception = message != null ? new HttpResponseException(command, response, message)
|
Exception exception = message != null ? new HttpResponseException(command, response, message)
|
||||||
: new HttpResponseException(command, response);
|
: new HttpResponseException(command, response);
|
||||||
try {
|
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
|
||||||
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
|
response.getStatusLine());
|
||||||
response.getStatusLine());
|
switch (response.getStatusCode()) {
|
||||||
switch (response.getStatusCode()) {
|
case 401:
|
||||||
case 401:
|
case 403:
|
||||||
case 403:
|
exception = new AuthorizationException(message, exception);
|
||||||
exception = new AuthorizationException(message, exception);
|
break;
|
||||||
break;
|
case 404:
|
||||||
case 404:
|
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
||||||
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
exception = new ResourceNotFoundException(message, exception);
|
||||||
exception = new ResourceNotFoundException(message, exception);
|
}
|
||||||
}
|
break;
|
||||||
break;
|
default:
|
||||||
case 500:
|
exception = new HttpResponseException(command, response, message);
|
||||||
if (message != null && message.indexOf("Unable to determine package for") != -1) {
|
break;
|
||||||
exception = new ResourceNotFoundException(message, exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (response.getPayload() != null)
|
|
||||||
Closeables.closeQuietly(response.getPayload().getInput());
|
|
||||||
command.setException(exception);
|
|
||||||
}
|
}
|
||||||
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap.Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class NovaUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The traditional way to represent a graph in Java is Map<V, Set<V>>, which is awkward in a
|
||||||
|
* number of ways. Guava's Multimap framework makes it easy to handle a mapping from keys to
|
||||||
|
* multiple values.
|
||||||
|
* <p/>
|
||||||
|
* Until we write or discover a gson Multimap deserializer, we may be stuck with this.
|
||||||
|
*
|
||||||
|
* TODO: ask on stackoverflow and/or jesse wilson
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static <K, V> Map<K, Set<V>> toOldSchool(Multimap<K, V> in) {
|
||||||
|
ImmutableMap.Builder<K, Set<V>> out = ImmutableMap.<K, Set<V>> builder();
|
||||||
|
for (K type : in.keySet())
|
||||||
|
out.put(type, ImmutableSet.copyOf(in.get(type)));
|
||||||
|
return out.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #toOldSchool
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static <K, V> ImmutableMultimap<K, V> fromOldSchool(Map<K, Set<V>> in) {
|
||||||
|
Builder<K, V> out = ImmutableMultimap.<K, V> builder();
|
||||||
|
for (K type : in.keySet())
|
||||||
|
out.putAll(type, ImmutableSet.copyOf(in.get(type)));
|
||||||
|
return out.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,11 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1;
|
package org.jclouds.openstack.nova.v1_1;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
import static org.easymock.EasyMock.expect;
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.easymock.EasyMock.reportMatcher;
|
import static org.easymock.EasyMock.reportMatcher;
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.EasyMock.verify;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
|
||||||
import static org.easymock.classextension.EasyMock.verify;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ import org.jclouds.http.HttpCommand;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.io.Payloads;
|
import org.jclouds.io.Payloads;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
import org.jclouds.openstack.nova.v1_1.handlers.NovaErrorHandler;
|
|
||||||
import org.jclouds.util.Strings2;
|
import org.jclouds.util.Strings2;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -46,26 +46,15 @@ import com.google.inject.Guice;
|
||||||
@Test(groups = { "unit" })
|
@Test(groups = { "unit" })
|
||||||
public class NovaErrorHandlerTest {
|
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
|
@Test
|
||||||
public void test401MakesAuthorizationException() {
|
public void test401MakesAuthorizationException() {
|
||||||
assertCodeMakes("GET", URI.create("https://api.openstack.nova.v1_1.com/foo"), 401, "", "Unauthorized",
|
assertCodeMakes("GET", URI.create("https://api.openstack.nova.com/foo"), 401, "", "Unauthorized",
|
||||||
AuthorizationException.class);
|
AuthorizationException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test404MakesResourceNotFoundException() {
|
public void test404MakesResourceNotFoundException() {
|
||||||
assertCodeMakes("GET", URI.create("https://api.openstack.nova.v1_1.com/foo"), 404, "", "Not Found",
|
assertCodeMakes("GET", URI.create("https://api.openstack.nova.com/foo"), 404, "", "Not Found",
|
||||||
ResourceNotFoundException.class);
|
ResourceNotFoundException.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package org.jclouds.openstack.nova.v1_1.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.parse.ParseServerTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests annotation parsing of {@code ServerAsyncClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ServerAsyncClientTest")
|
||||||
|
public class ServerClientExpectTest extends BaseNovaRestClientExpectTest {
|
||||||
|
|
||||||
|
public ServerClientExpectTest() {
|
||||||
|
provider = "openstack-nova";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListServersWhenResponseIs2xx() throws Exception {
|
||||||
|
HttpRequest listServers = HttpRequest.builder().method("GET")
|
||||||
|
.endpoint(URI.create("http://localhost:8774/v1.1/identity/servers"))
|
||||||
|
.headers(ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload(
|
||||||
|
payloadFromResource("/server_list.json")).build();
|
||||||
|
|
||||||
|
ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithUrls, listServers,
|
||||||
|
listServersResponse).getServerClient();
|
||||||
|
|
||||||
|
assertEquals(clientWhenServersExist.listServers().toString(), new ParseServerListTest().expected().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListServersWhenReponseIs404IsEmpty() throws Exception {
|
||||||
|
HttpRequest listServers = HttpRequest.builder().method("GET")
|
||||||
|
.endpoint(URI.create("http://localhost:8774/v1.1/identity/servers"))
|
||||||
|
.headers(ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse listServersResponse = HttpResponse.builder().statusCode(404).build();
|
||||||
|
|
||||||
|
ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithUrls, listServers,
|
||||||
|
listServersResponse).getServerClient();
|
||||||
|
|
||||||
|
assertTrue(clientWhenServersExist.listServers().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: gson deserializer for Multimap
|
||||||
|
@Test
|
||||||
|
public void testGetServerWhenResponseIs2xx() throws Exception {
|
||||||
|
HttpRequest listServers = HttpRequest.builder().method("GET")
|
||||||
|
.endpoint(URI.create("http://localhost:8774/v1.1/identity/servers/foo"))
|
||||||
|
.headers(ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("Accept", "application/json")
|
||||||
|
.put("X-Auth-Token", authToken).build()).build();
|
||||||
|
|
||||||
|
HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload(
|
||||||
|
payloadFromResource("/server_details.json")).build();
|
||||||
|
|
||||||
|
ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithUrls, listServers,
|
||||||
|
listServersResponse).getServerClient();
|
||||||
|
|
||||||
|
assertEquals(clientWhenServersExist.getServer("foo").toString(), new ParseServerTest().expected().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,8 +23,9 @@ import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Resource;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientLiveTest;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ import org.testng.annotations.Test;
|
||||||
@Test(groups = "live", testName = "ServerClientLiveTest")
|
@Test(groups = "live", testName = "ServerClientLiveTest")
|
||||||
public class ServerClientLiveTest extends BaseNovaClientLiveTest {
|
public class ServerClientLiveTest extends BaseNovaClientLiveTest {
|
||||||
|
|
||||||
@BeforeGroups(groups = {"live"})
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
super.setupClient();
|
super.setupClient();
|
||||||
client = context.getApi().getServerClient();
|
client = context.getApi().getServerClient();
|
||||||
|
@ -45,24 +46,20 @@ public class ServerClientLiveTest extends BaseNovaClientLiveTest {
|
||||||
private ServerClient client;
|
private ServerClient client;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListServers() throws Exception {
|
public void testListServersInDetail() throws Exception {
|
||||||
Set<Server> response = client.listServers();
|
Set<Resource> response = client.listServers();
|
||||||
assert null != response;
|
assert null != response;
|
||||||
assertTrue(response.size() >= 0);
|
assertTrue(response.size() >= 0);
|
||||||
for (Server server : response) {
|
for (Resource server : response) {
|
||||||
ServerDetails newDetails = client.getServerDetails(server.getId());
|
Server newDetails = client.getServer(server.getId());
|
||||||
assertEquals(newDetails.getId(), server.getId());
|
assertEquals(newDetails.getId(), server.getId());
|
||||||
assertEquals(newDetails.getHostname(), server.getHostname());
|
assertEquals(newDetails.getName(), server.getName());
|
||||||
assertEquals(newDetails.getPlatform(), server.getPlatform());
|
assertEquals(newDetails.getLinks(), server.getLinks());
|
||||||
assertEquals(newDetails.getDatacenter(), server.getDatacenter());
|
|
||||||
checkServer(newDetails);
|
checkServer(newDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkServer(ServerDetails server) {
|
private void checkServer(Server server) {
|
||||||
// description can be null
|
assert server.getAddresses().size() > 0 : server;
|
||||||
assert server.getCpuCores() > 0 : server;
|
|
||||||
assert server.getDisk() > 0 : server;
|
|
||||||
assert server.getMemory() > 0 : server;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1.features;
|
package org.jclouds.openstack.nova.v1_1.internal;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1.features;
|
package org.jclouds.openstack.nova.v1_1.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseVersionedServiceLiveTest;
|
||||||
|
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.RestContextFactory;
|
import org.jclouds.rest.RestContextFactory;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
@ -39,18 +40,20 @@ import com.google.inject.Module;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live")
|
@Test(groups = "live")
|
||||||
public class BaseNovaClientLiveTest {
|
public class BaseNovaClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
|
public BaseNovaClientLiveTest() {
|
||||||
|
provider = "openstack-nova";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected RestContext<NovaClient, NovaAsyncClient> context;
|
protected RestContext<NovaClient, NovaAsyncClient> context;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
String identity = checkNotNull(System.getProperty("test.openstack.nova.v1_1.identity"), "test.openstack.nova.v1_1.identity");
|
setupCredentials();
|
||||||
String credential = checkNotNull(System.getProperty("test.openstack.nova.v1_1.credential"), "test.openstack.nova.v1_1.credential");
|
Properties overrides = setupProperties();
|
||||||
|
context = new RestContextFactory().createContext(provider, identity, credential,
|
||||||
context = new RestContextFactory().createContext("openstack-nova", identity, credential,
|
ImmutableSet.<Module> of(new SLF4JLoggingModule(), new SshjSshClientModule()), overrides);
|
||||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterGroups(groups = "live")
|
@AfterGroups(groups = "live")
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.RequiresHttp;
|
||||||
|
import org.jclouds.openstack.config.OpenStackAuthenticationModule;
|
||||||
|
import org.jclouds.openstack.filters.AddTimestampQuery;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
||||||
|
import org.jclouds.rest.BaseRestClientExpectTest;
|
||||||
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for writing Nova Rest Client Expect tests
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class BaseNovaRestClientExpectTest extends BaseRestClientExpectTest<NovaClient> {
|
||||||
|
|
||||||
|
|
||||||
|
public BaseNovaRestClientExpectTest() {
|
||||||
|
provider = "openstack-nova";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: change to keystone
|
||||||
|
protected HttpRequest initialAuth = HttpRequest.builder().method("GET").endpoint(URI.create("http://localhost:5000/v1.1"))
|
||||||
|
.headers(
|
||||||
|
ImmutableMultimap.<String, String> builder()
|
||||||
|
.put("X-Auth-User", "identity")
|
||||||
|
.put("X-Auth-Key", "credential")
|
||||||
|
.put("Accept", "*/*").build()).build();
|
||||||
|
|
||||||
|
protected String authToken = "d6245d35-22a0-47c0-9770-2c5097da25fc";
|
||||||
|
|
||||||
|
// FIXME: KeyStone
|
||||||
|
protected HttpResponse responseWithUrls = HttpResponse
|
||||||
|
.builder()
|
||||||
|
.statusCode(204)
|
||||||
|
.message("HTTP/1.1 204 No Content")
|
||||||
|
.headers(ImmutableMultimap.<String,String>builder()
|
||||||
|
.put("Server", "Apache/2.2.3 (Red Hat)")
|
||||||
|
.put("vary", "X-Auth-Token,X-Auth-Key,X-Storage-User,X-Storage-Pass")
|
||||||
|
.put("Cache-Control", "s-maxage=86399")
|
||||||
|
.put("Content-Type", "text/xml")
|
||||||
|
.put("Date", "Tue, 10 Jan 2012 22:08:47 GMT")
|
||||||
|
.put("X-Auth-Token", authToken)
|
||||||
|
.put("X-Server-Management-Url","http://localhost:8774/v1.1/identity")
|
||||||
|
.put("Connection", "Keep-Alive")
|
||||||
|
.put("Content-Length", "0")
|
||||||
|
.build()).build();
|
||||||
|
|
||||||
|
|
||||||
|
protected static final String CONSTANT_DATE = "2009-11-08T15:54:08.897Z";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* override so that we can control the timestamp used in {@link AddTimestampQuery}
|
||||||
|
*/
|
||||||
|
static class TestOpenStackAuthenticationModule extends OpenStackAuthenticationModule {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<Date> provideCacheBusterDate() {
|
||||||
|
return new Supplier<Date>() {
|
||||||
|
public Date get() {
|
||||||
|
return new SimpleDateFormatDateService().iso8601DateParse(CONSTANT_DATE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Module createModule() {
|
||||||
|
return new TestNovaRestClientModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfiguresRestClient
|
||||||
|
@RequiresHttp
|
||||||
|
protected static class TestNovaRestClientModule extends NovaRestClientModule {
|
||||||
|
private TestNovaRestClientModule() {
|
||||||
|
super(new TestOpenStackAuthenticationModule());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* 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.net.URI;
|
||||||
|
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.Link;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Resource;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Link.Relation;
|
||||||
|
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<Resource> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/server_list.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("servers")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Set<Resource> expected() {
|
||||||
|
return ImmutableSet
|
||||||
|
.of(
|
||||||
|
Resource
|
||||||
|
.builder()
|
||||||
|
.id("52415800-8b69-11e0-9b19-734f6af67565")
|
||||||
|
.name("sample-server")
|
||||||
|
.links(
|
||||||
|
Link
|
||||||
|
.create(
|
||||||
|
Relation.SELF,
|
||||||
|
URI
|
||||||
|
.create("http://servers.api.openstack.org/v1.1/1234/servers/52415800-8b69-11e0-9b19-734f6af67565")),
|
||||||
|
Link
|
||||||
|
.create(
|
||||||
|
Relation.BOOKMARK,
|
||||||
|
URI
|
||||||
|
.create("http://servers.api.openstack.org/1234/servers/52415800-8b69-11e0-9b19-734f6af67565")))
|
||||||
|
.build(),
|
||||||
|
Resource
|
||||||
|
.builder()
|
||||||
|
.id("52415800-8b69-11e0-9b19-734f1f1350e5")
|
||||||
|
.name("sample-server2")
|
||||||
|
.links(
|
||||||
|
Link
|
||||||
|
.create(
|
||||||
|
Relation.SELF,
|
||||||
|
URI
|
||||||
|
.create("http://servers.api.openstack.org/v1.1/1234/servers/52415800-8b69-11e0-9b19-734f1f1350e5")),
|
||||||
|
Link
|
||||||
|
.create(
|
||||||
|
Relation.BOOKMARK,
|
||||||
|
URI
|
||||||
|
.create("http://servers.api.openstack.org/1234/servers/52415800-8b69-11e0-9b19-734f1f1350e5")))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -24,7 +24,8 @@ import javax.ws.rs.core.MediaType;
|
||||||
import org.jclouds.json.BaseItemParserTest;
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.ServerDetails;
|
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -32,27 +33,31 @@ import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "ParseServerDetailsTest")
|
@Test(groups = "unit", testName = "ParseServerTest")
|
||||||
public class ParseServerDetailsTest extends BaseItemParserTest<ServerDetails> {
|
public class ParseServerTest extends BaseItemParserTest<Server> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String resource() {
|
public String resource() {
|
||||||
return "/server.json";
|
return "/server_details.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SelectJson("server")
|
@SelectJson("server")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public ServerDetails expected() {
|
public Server expected() {
|
||||||
return ServerDetails.builder().id("vz1541880").hostname("mammamia").datacenter("Falkenberg").platform("OpenVZ")
|
return Server
|
||||||
.description("description").cpuCores(1).memory(128).disk(5).build();
|
.builder()
|
||||||
|
.id("52415800-8b69-11e0-9b19-734f000004d2")
|
||||||
|
.name("sample-server")
|
||||||
|
.publicAddresses(Address.createV4("67.23.10.132"), Address.createV6("::babe:67.23.10.132"),
|
||||||
|
Address.createV4("67.23.10.131"), Address.createV6("::babe:4317:0A83")).privateAddresses(
|
||||||
|
Address.createV4("10.176.42.16"), Address.createV6("::babe:10.176.42.16")).build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Injector injector() {
|
protected Injector injector() {
|
||||||
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration scan="false">
|
||||||
|
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds.log</file>
|
||||||
|
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds-wire.log</file>
|
||||||
|
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="COMPUTEFILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds-compute.log</file>
|
||||||
|
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="SSHFILE" class="ch.qos.logback.core.FileAppender">
|
||||||
|
<file>target/test-data/jclouds-ssh.log</file>
|
||||||
|
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<Pattern>%d %-5p [%c] (%t) %m%n</Pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root>
|
||||||
|
<level value="warn" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<logger name="org.jclouds">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="FILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.wire">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.headers">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="WIREFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.compute">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<logger name="jclouds.ssh">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
<appender-ref ref="SSHFILE" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
</configuration>
|
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"id": "52415800-8b69-11e0-9b19-734f000004d2",
|
||||||
|
"tenant_id": "1234",
|
||||||
|
"user_id": "5678",
|
||||||
|
"name": "sample-server",
|
||||||
|
"updated": "2010-10-10T12:00:00Z",
|
||||||
|
"created": "2010-08-10T12:00:00Z",
|
||||||
|
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||||
|
"accessIPv4" : "67.23.10.132",
|
||||||
|
"accessIPv6" : "::babe:67.23.10.132",
|
||||||
|
"status": "BUILD",
|
||||||
|
"progress": 60,
|
||||||
|
"image" : {
|
||||||
|
"id": "52415800-8b69-11e0-9b19-734f6f006e54",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"href": "http://servers.api.openstack.org/v1.1/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "bookmark",
|
||||||
|
"href": "http://servers.api.openstack.org/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"flavor" : {
|
||||||
|
"id": "52415800-8b69-11e0-9b19-734f216543fd",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"href": "http://servers.api.openstack.org/v1.1/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "bookmark",
|
||||||
|
"href": "http://servers.api.openstack.org/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"addresses": {
|
||||||
|
"public" : [
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"addr": "67.23.10.132"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"addr": "::babe:67.23.10.132"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"addr": "67.23.10.131"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"addr": "::babe:4317:0A83"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"private" : [
|
||||||
|
{
|
||||||
|
"version": 4,
|
||||||
|
"addr": "10.176.42.16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"addr": "::babe:10.176.42.16"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"Server Label": "Web Head 1",
|
||||||
|
"Image Version": "2.1"
|
||||||
|
},
|
||||||
|
"links": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"id": "52415800-8b69-11e0-9b19-734f6af67565",
|
||||||
|
"name": "sample-server",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"href": "http://servers.api.openstack.org/v1.1/1234/servers/52415800-8b69-11e0-9b19-734f6af67565"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "bookmark",
|
||||||
|
"href": "http://servers.api.openstack.org/1234/servers/52415800-8b69-11e0-9b19-734f6af67565"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "52415800-8b69-11e0-9b19-734f1f1350e5",
|
||||||
|
"name": "sample-server2",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"href": "http://servers.api.openstack.org/v1.1/1234/servers/52415800-8b69-11e0-9b19-734f1f1350e5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "bookmark",
|
||||||
|
"href": "http://servers.api.openstack.org/1234/servers/52415800-8b69-11e0-9b19-734f1f1350e5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?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>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<version>1.4.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.jclouds.labs</groupId>
|
||||||
|
<artifactId>jclouds-labs-project</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<name>jclouds labs project</name>
|
||||||
|
<modules>
|
||||||
|
<module>openstack-nova</module>
|
||||||
|
</modules>
|
||||||
|
</project>
|
1
pom.xml
1
pom.xml
|
@ -40,6 +40,7 @@
|
||||||
<module>compute</module>
|
<module>compute</module>
|
||||||
<module>loadbalancer</module>
|
<module>loadbalancer</module>
|
||||||
<module>apis</module>
|
<module>apis</module>
|
||||||
|
<module>labs</module>
|
||||||
<module>providers</module>
|
<module>providers</module>
|
||||||
<module>blobstore</module>
|
<module>blobstore</module>
|
||||||
<module>skeletons</module>
|
<module>skeletons</module>
|
||||||
|
|
|
@ -1,160 +0,0 @@
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,150 +0,0 @@
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/**
|
|
||||||
* 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>>() {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
/**
|
|
||||||
* 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,151 +0,0 @@
|
||||||
<?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>
|
|
|
@ -1,54 +0,0 @@
|
||||||
{
|
|
||||||
"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": {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue