API is updated to use URI references

This commit is contained in:
Dmitri Babaev 2011-04-11 03:15:13 +04:00 committed by Dmitri Babaev
parent 1137e552ae
commit 95b060218a
13 changed files with 147 additions and 93 deletions

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.openstack.nova; package org.jclouds.openstack.nova;
import java.net.URI;
import java.net.URL;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -155,8 +157,8 @@ public interface NovaAsyncClient {
@QueryParams(keys = "format", values = "json") @QueryParams(keys = "format", values = "json")
@Path("/servers") @Path("/servers")
@MapBinder(CreateServerOptions.class) @MapBinder(CreateServerOptions.class)
ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageId") int imageId, ListenableFuture<Server> createServer(@PayloadParam("name") String name, @PayloadParam("imageRef") String imageRef,
@PayloadParam("flavorId") int flavorId, CreateServerOptions... options); @PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
/** /**
* @see NovaClient#rebuildServer * @see NovaClient#rebuildServer

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.openstack.nova; package org.jclouds.openstack.nova;
import java.net.URI;
import java.net.URL;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -152,7 +154,7 @@ public interface NovaClient {
* @param options * @param options
* - used to specify extra files, metadata, or ip parameters during server creation. * - used to specify extra files, metadata, or ip parameters during server creation.
*/ */
Server createServer(String name, int imageId, int flavorId, CreateServerOptions... options); Server createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
/** /**
* The rebuild function removes all data on the server and replaces it with the specified image. * The rebuild function removes all data on the server and replaces it with the specified image.

View File

@ -36,8 +36,13 @@ import com.google.common.collect.ImmutableList;
@Singleton @Singleton
public class FlavorToHardware implements Function<Flavor, Hardware> { public class FlavorToHardware implements Function<Flavor, Hardware> {
public Hardware apply(Flavor from) { public Hardware apply(Flavor from) {
return new HardwareBuilder().ids(from.getId() + "").name(from.getName()) return new HardwareBuilder()
.processors(ImmutableList.of(new Processor(from.getDisk() / 10.0, 1.0))).ram(from.getRam()) .ids(from.getId() + "")
.volumes(ImmutableList.<Volume> of(new VolumeImpl((float) from.getDisk(), true, true))).build(); .name(from.getName())
.processors(ImmutableList.of(new Processor(from.getDisk() / 10.0, 1.0)))
.ram(from.getRam())
.volumes(ImmutableList.<Volume> of(new VolumeImpl((float) from.getDisk(), true, true)))
.uri(from.getURI())
.build();
} }
} }

View File

@ -28,6 +28,9 @@ import org.jclouds.domain.Credentials;
import com.google.common.base.Function; import com.google.common.base.Function;
import java.util.List;
import java.util.Map;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
@ -49,6 +52,7 @@ public class NovaImageToImage implements Function<org.jclouds.openstack.nova.dom
builder.version(from.getUpdated().getTime() + ""); builder.version(from.getUpdated().getTime() + "");
builder.operatingSystem(imageToOs.apply(from)); //image name may not represent the OS type builder.operatingSystem(imageToOs.apply(from)); //image name may not represent the OS type
builder.defaultCredentials(new Credentials("root", null)); builder.defaultCredentials(new Credentials("root", null));
builder.uri(from.getURI());
Image image = builder.build(); Image image = builder.build();
return image; return image;
} }

View File

@ -119,6 +119,7 @@ public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
builder.publicAddresses(from.getAddresses().getPublicAddresses()); builder.publicAddresses(from.getAddresses().getPublicAddresses());
builder.privateAddresses(from.getAddresses().getPrivateAddresses()); builder.privateAddresses(from.getAddresses().getPrivateAddresses());
builder.credentials(credentialStore.get("node#" + from.getId())); builder.credentials(credentialStore.get("node#" + from.getId()));
builder.uri(from.getURI());
return builder.build(); return builder.build();
} }

View File

@ -53,8 +53,8 @@ public class NovaCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGro
@Override @Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) {
Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer Server from = client.createServer(name, template.getImage().getUri().toString(),
.parseInt(template.getHardware().getProviderId())); template.getHardware().getUri().toString());
credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass())); credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass()));
return serverToNodeMetadata.apply(from); return serverToNodeMetadata.apply(from);
} }

View File

@ -25,7 +25,7 @@ package org.jclouds.openstack.nova.domain;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Flavor { public class Flavor extends Resource {
public Flavor() { public Flavor() {
} }

View File

@ -18,7 +18,20 @@
*/ */
package org.jclouds.openstack.nova.domain; package org.jclouds.openstack.nova.domain;
import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import javax.annotation.Nullable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map;
/** /**
* An image is a collection of files used to create or rebuild a server. Rackspace provides a number * An image is a collection of files used to create or rebuild a server. Rackspace provides a number
@ -28,7 +41,7 @@ import java.util.Date;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Image { public class Image extends Resource {
private Date created; private Date created;
private int id; private int id;
@ -37,6 +50,7 @@ public class Image {
private Integer serverId; private Integer serverId;
private ImageStatus status; private ImageStatus status;
private Date updated; private Date updated;
private Map<String, String> metadata = Maps.newHashMap();
public Image() { public Image() {
} }
@ -101,8 +115,17 @@ public class Image {
public Date getUpdated() { public Date getUpdated() {
return updated; return updated;
} }
public Map<String, String> getMetadata() {
return Collections.unmodifiableMap(metadata);
}
public void setMetadata(Map<String, String> metadata) {
this.metadata = Maps.newHashMap(metadata);
}
/** /**
* note that this ignores the create time * note that this ignores some fields
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
@ -115,7 +138,7 @@ public class Image {
} }
/** /**
* note that this ignores the serverid and create time. * note that this ignores some fields
*/ */
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {

View File

@ -0,0 +1,27 @@
package org.jclouds.openstack.nova.domain;
import com.google.common.collect.Lists;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
/**
* @author Dmitri Babaev
*/
public class Resource {
private List<Map<String, String>> links = Lists.newArrayList();
public URI getURI() {
for (Map<String, String> linkProperties : links) {
try {
return new URI(linkProperties.get("href"));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
throw new IllegalStateException("URI is not available");
}
}

View File

@ -28,7 +28,7 @@ import com.google.common.collect.Maps;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Server { public class Server extends Resource {
private int id; private int id;
private String name; private String name;
@ -39,7 +39,6 @@ public class Server {
private Integer flavorId; private Integer flavorId;
private String hostId; private String hostId;
private Integer imageId; private Integer imageId;
private Integer sharedIpGroupId;
private Integer progress; private Integer progress;
private ServerStatus status; private ServerStatus status;
@ -124,14 +123,6 @@ public class Server {
return progress; return progress;
} }
public void setSharedIpGroupId(Integer sharedIpGroupId) {
this.sharedIpGroupId = sharedIpGroupId;
}
public Integer getSharedIpGroupId() {
return sharedIpGroupId;
}
public void setStatus(ServerStatus status) { public void setStatus(ServerStatus status) {
this.status = status; this.status = status;
} }
@ -156,7 +147,6 @@ public class Server {
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((metadata == null) ? 0 : metadata.hashCode()); result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sharedIpGroupId == null) ? 0 : sharedIpGroupId.hashCode());
return result; return result;
} }
@ -206,11 +196,6 @@ public class Server {
return false; return false;
} else if (!name.equals(other.name)) } else if (!name.equals(other.name))
return false; return false;
if (sharedIpGroupId == null) {
if (other.sharedIpGroupId != null)
return false;
} else if (!sharedIpGroupId.equals(other.sharedIpGroupId))
return false;
return true; return true;
} }
@ -222,8 +207,7 @@ public class Server {
public String toString() { public String toString() {
return "Server [addresses=" + addresses + ", adminPass=" + adminPass + ", flavorId=" return "Server [addresses=" + addresses + ", adminPass=" + adminPass + ", flavorId="
+ flavorId + ", hostId=" + hostId + ", id=" + id + ", imageId=" + imageId + flavorId + ", hostId=" + hostId + ", id=" + id + ", imageId=" + imageId
+ ", metadata=" + metadata + ", name=" + name + ", sharedIpGroupId=" + ", metadata=" + metadata + ", name=" + name + "]";
+ sharedIpGroupId + "]";
} }
} }

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -70,17 +71,17 @@ public class CreateServerOptions extends BindToJsonPayload {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private class ServerRequest { private class ServerRequest {
final String name; final String name;
final int imageId; final String imageRef;
final int flavorId; final String flavorRef;
Map<String, String> metadata; Map<String, String> metadata;
List<File> personality; List<File> personality;
Integer sharedIpGroupId; Integer sharedIpGroupId;
Addresses addresses; Addresses addresses;
private ServerRequest(String name, int imageId, int flavorId) { private ServerRequest(String name, String imageRef, String flavorRef) {
this.name = name; this.name = name;
this.imageId = imageId; this.imageRef = imageRef;
this.flavorId = flavorId; this.flavorRef = flavorRef;
} }
} }
@ -93,9 +94,9 @@ public class CreateServerOptions extends BindToJsonPayload {
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) { public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"), ServerRequest server = new ServerRequest(checkNotNull(postParams.get("name"),
"name parameter not present"), Integer.parseInt(checkNotNull(postParams "name parameter not present"), checkNotNull(postParams
.get("imageId"), "imageId parameter not present")), Integer.parseInt(checkNotNull( .get("imageRef"), "imageRef parameter not present"), checkNotNull(
postParams.get("flavorId"), "flavorId parameter not present"))); postParams.get("flavorRef"), "flavorRef parameter not present"));
if (metadata.size() > 0) if (metadata.size() > 0)
server.metadata = metadata; server.metadata = metadata;
if (files.size() > 0) if (files.size() > 0)

View File

@ -46,6 +46,7 @@ import org.testng.annotations.Test;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -271,13 +272,13 @@ public class NovaClientLiveTest {
@Test(enabled = true) @Test(enabled = true)
public void testCreateServer() throws Exception { public void testCreateServer() throws Exception {
int imageId = 14362; String imageRef = "14362";
int flavorId = 1; String flavorRef = "1";
Server server = null; Server server = null;
while (server == null) { while (server == null) {
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt(); String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
try { try {
server = client.createServer(serverName, imageId, flavorId, withFile("/etc/jclouds.txt", server = client.createServer(serverName, imageRef, flavorRef, withFile("/etc/jclouds.txt",
"rackspace".getBytes()).withMetadata(metadata)); "rackspace".getBytes()).withMetadata(metadata));
} catch (UndeclaredThrowableException e) { } catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause(); HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();

View File

@ -1,52 +1,56 @@
package org.jclouds.openstack.nova; package org.jclouds.openstack.nova;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException; import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import java.util.Collections;
import java.util.Properties; import java.util.Arrays;
import java.util.Collections;
import static org.jclouds.Constants.PROPERTY_ENDPOINT; import java.util.Properties;
public class _NovaClient { import static org.jclouds.Constants.PROPERTY_ENDPOINT;
static public void main(String[] args) {
//curl -v -H "X-Auth-User:admin" -H "X-Auth-Key: d744752f-20d3-4d75-979f-f62f16033b07" http://172.18.34.40:8774/v1.0/ public class _NovaClient {
//curl -v -H "X-Auth-Token: c97b10659008d5a9ce91462f8c6a5c2c80439762" http://172.18.34.40:8774/v1.0/images/detail?format=json static public void main(String[] args) {
//curl -v -H "X-Auth-User:admin" -H "X-Auth-Key: d744752f-20d3-4d75-979f-f62f16033b07" http://172.18.34.40:8774/v1.0/
String identity = "admin"; //curl -v -H "X-Auth-Token: c97b10659008d5a9ce91462f8c6a5c2c80439762" http://172.18.34.40:8774/v1.0/images/detail?format=json
String credential = "d744752f-20d3-4d75-979f-f62f16033b07";
String endpoint = "http://172.18.34.40:8774"; String identity = "admin";
String credential = "d744752f-20d3-4d75-979f-f62f16033b07";
ComputeServiceContextFactory contextFactory = new ComputeServiceContextFactory(); String endpoint = "http://dragon004.hw.griddynamics.net:8774";
Properties overrides = new Properties(); ComputeServiceContextFactory contextFactory = new ComputeServiceContextFactory();
overrides.setProperty(PROPERTY_ENDPOINT, endpoint);
ComputeServiceContext context = contextFactory.createContext("nova", identity, credential, Collections.singleton(new JschSshClientModule()), overrides); Properties overrides = new Properties();
overrides.setProperty(PROPERTY_ENDPOINT, endpoint);
ComputeService cs = context.getComputeService(); ComputeServiceContext context = contextFactory.createContext("nova", identity, credential,
Arrays.asList(new JschSshClientModule(), new Log4JLoggingModule()), overrides);
System.out.println(cs.listImages());
//System.out.println(cs.listNodes()); ComputeService cs = context.getComputeService();
TemplateOptions options = new TemplateOptions(); System.out.println(cs.listImages());
//options.authorizePublicKey(""); System.out.println(cs.listHardwareProfiles());
//Template template = cs.templateBuilder().hardwareId("m1.small").imageId("13").options(options).build(); //System.out.println(cs.listNodes());
//try {
// cs.runNodesWithTag("test", 1, template); TemplateOptions options = new TemplateOptions();
//} catch (RunNodesException e) { //options.authorizePublicKey("");
// e.printStackTrace(); Template template = cs.templateBuilder().imageId("13").options(options).build();
//} try {
cs.runNodesWithTag("test", 1, template);
//System.out.println(cs.listNodes()); } catch (RunNodesException e) {
//System.out.println(cs.listImages()); e.printStackTrace();
//System.out.println(cs.listNodes()); }
//System.out.println(cs.listAssignableLocations());
//System.out.println(cs.listHardwareProfiles()); //System.out.println(cs.listNodes());
} //System.out.println(cs.listImages());
} //System.out.println(cs.listNodes());
//System.out.println(cs.listAssignableLocations());
//System.out.println(cs.listHardwareProfiles());
}
}