mirror of https://github.com/apache/jclouds.git
Issue 112: missed files from last commit
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2713 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
cb906ded3c
commit
bc1c1fd793
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public interface VCloudComputeClient {
|
||||||
|
/**
|
||||||
|
* Runs through all commands necessary to startup a vApp, opening at least one ip address to the
|
||||||
|
* public network. These are the steps:
|
||||||
|
* <p/>
|
||||||
|
* instantiate -> deploy -> powerOn
|
||||||
|
* <p/>
|
||||||
|
* This command blocks until the vApp is in state {@code VAppStatus#ON}
|
||||||
|
*
|
||||||
|
* @param vDCId
|
||||||
|
* id of the virtual datacenter {@code VCloudClient#getDefaultVDC}
|
||||||
|
* @param name
|
||||||
|
* name of the vApp
|
||||||
|
* @param templateId
|
||||||
|
* id of the vAppTemplate you wish to instantiate
|
||||||
|
* @param cores
|
||||||
|
* amount of virtual cpu cores
|
||||||
|
* @param megs
|
||||||
|
* amount of ram in megabytes
|
||||||
|
* @param diskSizeKilobytes
|
||||||
|
* size of disk in kilobytes, null is ok
|
||||||
|
* @param properties
|
||||||
|
* sets product properties on the vApp
|
||||||
|
* @param portsToOpen
|
||||||
|
* opens the following ports on the public ip address
|
||||||
|
* @return map contains at least the following properties
|
||||||
|
* <ol>
|
||||||
|
* <li>id - vApp id</li> <li>username - console login user</li> <li>password - console
|
||||||
|
* login password</li>
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
Map<String, String> start(String vDCId, String name, String templateId, int cores, int megs,
|
||||||
|
@Nullable Long diskSizeKilobytes, Map<String, String> properties, int... portsToOpen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a set of addresses that are only visible to the private network.
|
||||||
|
*/
|
||||||
|
Set<InetAddress> getPrivateAddresses(String vAppId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns a set of addresses that are publically visible
|
||||||
|
*/
|
||||||
|
Set<InetAddress> getPublicAddresses(String vAppId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reboots the vApp, blocking until the following state transition is complete:
|
||||||
|
* <p/>
|
||||||
|
* current -> {@code VAppStatus#OFF} -> {@code VAppStatus#ON}
|
||||||
|
*
|
||||||
|
* @param vAppId
|
||||||
|
* vApp to reboot
|
||||||
|
*/
|
||||||
|
void reboot(String vAppId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys dependent resources, powers off and deletes the vApp, blocking until the following
|
||||||
|
* state transition is complete:
|
||||||
|
* <p/>
|
||||||
|
* current -> {@code VAppStatus#OFF} -> deleted
|
||||||
|
*
|
||||||
|
* @param vAppId
|
||||||
|
* vApp to stop
|
||||||
|
*/
|
||||||
|
void stop(String vAppId);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,338 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Provider;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
|
import org.jclouds.compute.domain.ComputeType;
|
||||||
|
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.LoginType;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.compute.domain.Size;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||||
|
import org.jclouds.compute.options.RunNodeOptions;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
|
import org.jclouds.vcloud.VCloudMediaType;
|
||||||
|
import org.jclouds.vcloud.domain.NamedResource;
|
||||||
|
import org.jclouds.vcloud.domain.Task;
|
||||||
|
import org.jclouds.vcloud.domain.VApp;
|
||||||
|
import org.jclouds.vcloud.domain.VAppStatus;
|
||||||
|
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class VCloudComputeService implements ComputeService, VCloudComputeClient {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
private final VCloudClient client;
|
||||||
|
protected final Provider<Set<? extends Image>> images;
|
||||||
|
protected final Provider<SortedSet<? extends Size>> sizes;
|
||||||
|
private final Provider<Set<? extends VCloudTemplate>> templates;
|
||||||
|
|
||||||
|
@Inject(optional = true)
|
||||||
|
private SshClient.Factory sshFactory;
|
||||||
|
private Predicate<InetSocketAddress> socketTester;
|
||||||
|
|
||||||
|
protected static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
|
||||||
|
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
|
||||||
|
VAppStatus.ON, NodeState.RUNNING).put(VAppStatus.RESOLVED, NodeState.PENDING)
|
||||||
|
.put(VAppStatus.SUSPENDED, NodeState.SUSPENDED).put(VAppStatus.UNRESOLVED,
|
||||||
|
NodeState.PENDING).build();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public VCloudComputeService(VCloudClient client, Provider<Set<? extends Image>> images,
|
||||||
|
Provider<SortedSet<? extends Size>> sizes,
|
||||||
|
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||||
|
Predicate<InetSocketAddress> socketTester) {
|
||||||
|
this.taskTester = successTester;
|
||||||
|
this.client = client;
|
||||||
|
this.images = images;
|
||||||
|
this.sizes = sizes;
|
||||||
|
this.templates = templates;
|
||||||
|
this.socketTester = socketTester;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CreateNodeResponse runNode(String name, Template template) {
|
||||||
|
return this.runNode(name, template, RunNodeOptions.NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
|
||||||
|
checkNotNull(template.getImage().getLocation(), "location");
|
||||||
|
Map<String, String> metaMap = start(template.getImage().getLocation(), name, template
|
||||||
|
.getImage().getId(), template.getSize().getCores(), template.getSize().getRam(),
|
||||||
|
template.getSize().getDisk() * 1024 * 1024l, ImmutableMap.<String, String> of(),
|
||||||
|
options.getOpenPorts());
|
||||||
|
VApp vApp = client.getVApp(metaMap.get("id"));
|
||||||
|
CreateNodeResponse node = newCreateNodeResponse(template, metaMap, vApp);
|
||||||
|
if (options.getRunScript() != null) {
|
||||||
|
checkState(this.sshFactory != null, "runScript requested, but no SshModule configured");
|
||||||
|
runScriptOnNode(node, options.getRunScript());
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runScriptOnNode(CreateNodeResponse node, byte[] script) {
|
||||||
|
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
|
||||||
|
.getLoginPort());
|
||||||
|
socketTester.apply(socket);
|
||||||
|
SshClient ssh = isKeyBasedAuth(node) ? sshFactory.create(socket,
|
||||||
|
node.getCredentials().account, node.getCredentials().key.getBytes()) : sshFactory
|
||||||
|
.create(socket, node.getCredentials().account, node.getCredentials().key);
|
||||||
|
try {
|
||||||
|
ssh.connect();
|
||||||
|
String scriptName = node.getId() + ".sh";
|
||||||
|
ssh.put(scriptName, new ByteArrayInputStream(script));
|
||||||
|
ssh.exec("chmod 755 " + scriptName);
|
||||||
|
if (node.getCredentials().account.equals("root")) {
|
||||||
|
logger.debug(ssh.exec("./" + scriptName).toString());
|
||||||
|
} else if (isKeyBasedAuth(node)) {
|
||||||
|
logger.debug(ssh.exec("sudo ./" + scriptName).toString());
|
||||||
|
} else {
|
||||||
|
logger.debug(ssh.exec(
|
||||||
|
String.format("echo %s|sudo -S ./%s", node.getCredentials().key, scriptName))
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (ssh != null)
|
||||||
|
ssh.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isKeyBasedAuth(CreateNodeResponse node) {
|
||||||
|
return node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CreateNodeResponse newCreateNodeResponse(Template template,
|
||||||
|
Map<String, String> metaMap, VApp vApp) {
|
||||||
|
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage()
|
||||||
|
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(),
|
||||||
|
vAppStatusToNodeState.get(vApp.getStatus()), getPublicAddresses(vApp.getId()),
|
||||||
|
getPrivateAddresses(vApp.getId()), 22, LoginType.SSH, new Credentials(metaMap
|
||||||
|
.get("username"), metaMap.get("password")), ImmutableMap
|
||||||
|
.<String, String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
|
||||||
|
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||||
|
+ node.getType());
|
||||||
|
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
|
||||||
|
node.getId(), "node.id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
|
||||||
|
VApp vApp = client.getVApp(id);
|
||||||
|
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
|
||||||
|
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
|
||||||
|
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22,
|
||||||
|
LoginType.SSH, ImmutableMap.<String, String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ComputeMetadata> listNodes() {
|
||||||
|
Set<ComputeMetadata> nodes = Sets.newHashSet();
|
||||||
|
for (NamedResource vdc : client.getDefaultOrganization().getVDCs().values()) {
|
||||||
|
for (NamedResource resource : client.getVDC(vdc.getId()).getResourceEntities().values()) {
|
||||||
|
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
|
||||||
|
nodes.add(getNodeMetadataByIdInVDC(vdc.getId(), resource.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyNode(ComputeMetadata node) {
|
||||||
|
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
|
||||||
|
+ node.getType());
|
||||||
|
stop(checkNotNull(node.getId(), "node.id"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Template createTemplateInLocation(String location) {
|
||||||
|
return new VCloudTemplate(client, images.get(), sizes.get(), location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SortedSet<? extends Size> listSizes() {
|
||||||
|
return sizes.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<? extends Template> listTemplates() {
|
||||||
|
return templates.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Predicate<String> taskTester;
|
||||||
|
|
||||||
|
public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
|
||||||
|
int minMegs, Long diskSize, Map<String, String> properties, int... portsToOpen) {
|
||||||
|
logger
|
||||||
|
.debug(
|
||||||
|
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
|
||||||
|
vDCId, name, templateId, minCores, minMegs, diskSize, properties);
|
||||||
|
InstantiateVAppTemplateOptions options = processorCount(minCores).memory(minMegs)
|
||||||
|
.productProperties(properties);
|
||||||
|
if (diskSize != null)
|
||||||
|
options.disk(diskSize);
|
||||||
|
VApp vAppResponse = client.instantiateVAppTemplateInVDC(vDCId, name, templateId, options);
|
||||||
|
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
|
||||||
|
|
||||||
|
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
|
||||||
|
VApp vApp = blockUntilVAppStatusOrThrowException(vAppResponse, client.deployVApp(vAppResponse
|
||||||
|
.getId()), "deploy", ImmutableSet.of(VAppStatus.OFF, VAppStatus.ON));
|
||||||
|
logger.debug("<< deployed vApp(%s)", vApp.getId());
|
||||||
|
|
||||||
|
logger.debug(">> powering vApp(%s)", vApp.getId());
|
||||||
|
vApp = blockUntilVAppStatusOrThrowException(vApp, client.powerOnVApp(vApp.getId()),
|
||||||
|
"powerOn", ImmutableSet.of(VAppStatus.ON));
|
||||||
|
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||||
|
Map<String, String> response = parseResponse(vAppResponse);
|
||||||
|
checkState(response.containsKey("id"), "bad configuration: [id] should be in response");
|
||||||
|
checkState(response.containsKey("username"),
|
||||||
|
"bad configuration: [username] should be in response");
|
||||||
|
checkState(response.containsKey("password"),
|
||||||
|
"bad configuration: [password] should be in response");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, String> parseResponse(VApp vAppResponse) {
|
||||||
|
return ImmutableMap.<String, String> of("id", vAppResponse.getId(), "username", "",
|
||||||
|
"password", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reboot(String id) {
|
||||||
|
VApp vApp = client.getVApp(id);
|
||||||
|
logger.debug(">> rebooting vApp(%s)", vApp.getId());
|
||||||
|
blockUntilVAppStatusOrThrowException(vApp, client.resetVApp(vApp.getId()), "reset",
|
||||||
|
ImmutableSet.of(VAppStatus.ON));
|
||||||
|
logger.debug("<< on vApp(%s)", vApp.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(String id) {
|
||||||
|
VApp vApp = client.getVApp(id);
|
||||||
|
if (vApp.getStatus() != VAppStatus.OFF) {
|
||||||
|
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp
|
||||||
|
.getStatus());
|
||||||
|
blockUntilVAppStatusOrThrowException(vApp, client.powerOffVApp(vApp.getId()), "powerOff",
|
||||||
|
ImmutableSet.of(VAppStatus.OFF));
|
||||||
|
logger.debug("<< off vApp(%s)", vApp.getId());
|
||||||
|
}
|
||||||
|
logger.debug(">> deleting vApp(%s)", vApp.getId());
|
||||||
|
client.deleteVApp(id);
|
||||||
|
logger.debug("<< deleted vApp(%s)", vApp.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
private VApp blockUntilVAppStatusOrThrowException(VApp vApp, Task deployTask, String taskType,
|
||||||
|
Set<VAppStatus> acceptableStatuses) {
|
||||||
|
if (!taskTester.apply(deployTask.getId())) {
|
||||||
|
throw new TaskException(taskType, vApp, deployTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
vApp = client.getVApp(vApp.getId());
|
||||||
|
if (!acceptableStatuses.contains(vApp.getStatus())) {
|
||||||
|
throw new VAppException(String.format("vApp %s status %s should be %s after %s", vApp
|
||||||
|
.getId(), vApp.getStatus(), acceptableStatuses, taskType), vApp);
|
||||||
|
}
|
||||||
|
return vApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TaskException extends VAppException {
|
||||||
|
|
||||||
|
private final Task task;
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 251801929573211256L;
|
||||||
|
|
||||||
|
public TaskException(String type, VApp vApp, Task task) {
|
||||||
|
super(String.format("failed to %s vApp %s status %s;task %s status %s", type,
|
||||||
|
vApp.getId(), vApp.getStatus(), task.getLocation(), task.getStatus()), vApp);
|
||||||
|
this.task = task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task getTask() {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class VAppException extends RuntimeException {
|
||||||
|
|
||||||
|
private final VApp vApp;
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 251801929573211256L;
|
||||||
|
|
||||||
|
public VAppException(String message, VApp vApp) {
|
||||||
|
super(message);
|
||||||
|
this.vApp = vApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VApp getvApp() {
|
||||||
|
return vApp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<InetAddress> getPrivateAddresses(String id) {
|
||||||
|
return ImmutableSet.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<InetAddress> getPublicAddresses(String id) {
|
||||||
|
VApp vApp = client.getVApp(id);
|
||||||
|
return Sets.newHashSet(vApp.getNetworkToAddresses().values());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||||
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
|
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule;
|
||||||
|
import org.jclouds.vcloud.config.VCloudRestClientModule;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates {@link VCloudComputeServiceContext} or {@link Injector} instances based on the most
|
||||||
|
* commonly requested arguments.
|
||||||
|
* <p/>
|
||||||
|
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||||
|
* <p/>
|
||||||
|
* <p/>
|
||||||
|
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||||
|
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see VCloudComputeServiceContext
|
||||||
|
*/
|
||||||
|
public class VCloudComputeServiceContextBuilder extends
|
||||||
|
ComputeServiceContextBuilder<VCloudAsyncClient, VCloudClient> {
|
||||||
|
|
||||||
|
public VCloudComputeServiceContextBuilder(Properties props) {
|
||||||
|
super(new TypeLiteral<VCloudAsyncClient>() {
|
||||||
|
}, new TypeLiteral<VCloudClient>() {
|
||||||
|
}, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VCloudComputeServiceContextBuilder withExecutorService(ExecutorService service) {
|
||||||
|
return (VCloudComputeServiceContextBuilder) super.withExecutorService(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VCloudComputeServiceContextBuilder withModules(Module... modules) {
|
||||||
|
return (VCloudComputeServiceContextBuilder) super.withModules(modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addContextModule(List<Module> modules) {
|
||||||
|
modules.add(new VCloudComputeServiceContextModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addClientModule(List<Module> modules) {
|
||||||
|
modules.add(new VCloudRestClientModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ComputeServiceContext buildComputeServiceContext() {
|
||||||
|
// need the generic type information
|
||||||
|
return (ComputeServiceContext) this
|
||||||
|
.buildInjector()
|
||||||
|
.getInstance(
|
||||||
|
Key
|
||||||
|
.get(new TypeLiteral<ComputeServiceContextImpl<VCloudAsyncClient, VCloudClient>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
|
import org.jclouds.vcloud.VCloudPropertiesBuilder;
|
||||||
|
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates {@link VCloudComputeServiceContext} instances based on the most commonly
|
||||||
|
* requested arguments.
|
||||||
|
* <p/>
|
||||||
|
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||||
|
* <p/>
|
||||||
|
* <p/>
|
||||||
|
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||||
|
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see VCloudComputeServiceContext
|
||||||
|
*/
|
||||||
|
public class VCloudComputeServiceContextFactory {
|
||||||
|
public static ComputeServiceContext createContext(Properties properties, Module... modules) {
|
||||||
|
return new VCloudComputeServiceContextBuilder(
|
||||||
|
new VCloudPropertiesBuilder(properties).build()).withModules(modules)
|
||||||
|
.buildComputeServiceContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComputeServiceContext createContext(Properties properties, String user,
|
||||||
|
String key, Module... modules) {
|
||||||
|
return new VCloudComputeServiceContextBuilder(
|
||||||
|
new VCloudPropertiesBuilder(properties).withCredentials(user, key)
|
||||||
|
.build()).withModules(modules).buildComputeServiceContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComputeServiceContext createContext(URI endpoint, String user, String key,
|
||||||
|
Module... modules) {
|
||||||
|
return new VCloudComputeServiceContextBuilder(
|
||||||
|
new VCloudPropertiesBuilder(endpoint, user, key).withEndpoint(endpoint).build())
|
||||||
|
.withModules(modules).buildComputeServiceContext();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.compute.domain.Size;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class VCloudTemplate implements Template {
|
||||||
|
private final VCloudClient client;
|
||||||
|
private final Set<? extends Image> images;
|
||||||
|
private final Set<? extends Size> sizes;
|
||||||
|
private Size size;
|
||||||
|
private String vDC;
|
||||||
|
private OperatingSystem operatingSystem;
|
||||||
|
private transient Image image;
|
||||||
|
|
||||||
|
public VCloudTemplate(VCloudClient client,
|
||||||
|
Set<? extends Image> images, Set<? extends Size> sizes, String location,
|
||||||
|
@Nullable Size size, OperatingSystem operatingSystem, @Nullable Image image) {
|
||||||
|
this.client = client;
|
||||||
|
this.images = images;
|
||||||
|
this.sizes = sizes;
|
||||||
|
this.vDC = location;
|
||||||
|
this.image = image != null ? image : resolveTemplate(images, operatingSystem);
|
||||||
|
this.size = size != null ? size : Iterables.get(sizes, 0);
|
||||||
|
this.operatingSystem = operatingSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image resolveTemplate(Set<? extends Image> images, OperatingSystem operatingSystem) {
|
||||||
|
for (Image image : images) {
|
||||||
|
if (image.getOperatingSystem() == operatingSystem)
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("no configured image matches os: " + operatingSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
VCloudTemplate(VCloudClient client, Set<? extends Image> images,
|
||||||
|
Set<? extends Size> sizes, String location) {
|
||||||
|
this(client, images, sizes, location, null, OperatingSystem.CENTOS, null);// note the default
|
||||||
|
// os
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Size getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Image getImage() {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Template smallest() {
|
||||||
|
this.size = Iterables.get(sizes, 0);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Template biggest() {
|
||||||
|
this.size = Iterables.getLast(sizes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Template fastest() {
|
||||||
|
this.size = Iterables.getLast(sizes);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Template inLocation(String location) {
|
||||||
|
if (location.equalsIgnoreCase("default"))
|
||||||
|
location = client.getDefaultVDC().getId();
|
||||||
|
this.vDC = location;// TODO match vdc on template as well arch
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Template os(OperatingSystem os) {
|
||||||
|
this.operatingSystem = os;
|
||||||
|
this.image = resolveTemplate(images, operatingSystem);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Object clone() throws CloneNotSupportedException {
|
||||||
|
return new VCloudTemplate(client, images, sizes, vDC, size, operatingSystem,
|
||||||
|
image);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getvDC() {
|
||||||
|
return vDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||||
|
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||||
|
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||||
|
result = prime * result + ((vDC == null) ? 0 : vDC.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;
|
||||||
|
VCloudTemplate other = (VCloudTemplate) obj;
|
||||||
|
if (image == null) {
|
||||||
|
if (other.image != null)
|
||||||
|
return false;
|
||||||
|
} else if (!image.equals(other.image))
|
||||||
|
return false;
|
||||||
|
if (operatingSystem == null) {
|
||||||
|
if (other.operatingSystem != null)
|
||||||
|
return false;
|
||||||
|
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||||
|
return false;
|
||||||
|
if (size == null) {
|
||||||
|
if (other.size != null)
|
||||||
|
return false;
|
||||||
|
} else if (!size.equals(other.size))
|
||||||
|
return false;
|
||||||
|
if (vDC == null) {
|
||||||
|
if (other.vDC != null)
|
||||||
|
return false;
|
||||||
|
} else if (!vDC.equals(other.vDC))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "VCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
|
||||||
|
+ ", size=" + size + ", vDC=" + vDC + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,199 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute.config;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.domain.Architecture;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.compute.domain.Size;
|
||||||
|
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||||
|
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
|
import org.jclouds.vcloud.VCloudMediaType;
|
||||||
|
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||||
|
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||||
|
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||||
|
import org.jclouds.vcloud.config.VCloudContextModule;
|
||||||
|
import org.jclouds.vcloud.domain.Catalog;
|
||||||
|
import org.jclouds.vcloud.domain.CatalogItem;
|
||||||
|
import org.jclouds.vcloud.domain.NamedResource;
|
||||||
|
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the {@link VCloudComputeServiceContext}; requires {@link VCloudComputeService} bound.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected ComputeService provideComputeService(Injector injector) {
|
||||||
|
return injector.getInstance(VCloudComputeService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected VCloudComputeClient provideComputeClient(VCloudComputeService in) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected ComputeServiceContext provideContext(ComputeService computeService,
|
||||||
|
RestContext<VCloudAsyncClient, VCloudClient> context) {
|
||||||
|
return new ComputeServiceContextImpl<VCloudAsyncClient, VCloudClient>(computeService, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class LogHolder {
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
public Logger logger = Logger.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Set<? extends Image> provideImages(final VCloudClient client, LogHolder holder,
|
||||||
|
ExecutorService executor) throws InterruptedException, ExecutionException,
|
||||||
|
TimeoutException {
|
||||||
|
final Set<Image> images = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> providing images");
|
||||||
|
Catalog response = client.getDefaultCatalog();
|
||||||
|
final String vDC = client.getDefaultVDC().getId();
|
||||||
|
Set<Future<Void>> responses = Sets.newHashSet();
|
||||||
|
|
||||||
|
for (final NamedResource resource : response.values()) {
|
||||||
|
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
|
||||||
|
final CatalogItem item = client.getCatalogItem(resource.getId());
|
||||||
|
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
|
||||||
|
responses.add(executor.submit(new Callable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
OperatingSystem myOs = OperatingSystem.UNKNOWN;
|
||||||
|
for (OperatingSystem os : OperatingSystem.values()) {
|
||||||
|
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(
|
||||||
|
os.toString()) != -1) {
|
||||||
|
myOs = os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
|
||||||
|
: Architecture.X86_64;
|
||||||
|
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
|
||||||
|
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs,
|
||||||
|
null, vDC, arch));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pollResponsesAndLogWhenComplete(images.size(), "images", holder, responses);
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void pollResponsesAndLogWhenComplete(int total, String description, LogHolder holder,
|
||||||
|
Set<Future<Void>> responses) throws InterruptedException, TimeoutException,
|
||||||
|
ExecutionException {
|
||||||
|
int complete = 0;
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
long timeOut = 60 * 1000;
|
||||||
|
do {
|
||||||
|
Set<Future<Void>> retries = Sets.newHashSet();
|
||||||
|
for (Future<Void> future : responses) {
|
||||||
|
try {
|
||||||
|
future.get(100, TimeUnit.MILLISECONDS);
|
||||||
|
complete++;
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
Throwables.propagate(e);
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
retries.add(future);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responses = Sets.newHashSet(retries);
|
||||||
|
} while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut);
|
||||||
|
long duration = System.currentTimeMillis() - start;
|
||||||
|
if (duration > timeOut)
|
||||||
|
throw new TimeoutException(String.format("TIMEOUT: %s(%d/%d) rate: %f %s/second%n",
|
||||||
|
description, complete, total, ((double) complete) / (duration / 1000.0),
|
||||||
|
description));
|
||||||
|
for (Future<Void> future : responses)
|
||||||
|
future.get(30, TimeUnit.SECONDS);
|
||||||
|
holder.logger.debug("<< %s(%d) rate: %f %s/second%n", description, total, ((double) complete)
|
||||||
|
/ (duration / 1000.0), description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected SortedSet<? extends Size> provideSizes(VCloudClient client,
|
||||||
|
Set<? extends Image> images, LogHolder holder, ExecutorService executor)
|
||||||
|
throws InterruptedException, TimeoutException, ExecutionException {
|
||||||
|
return ImmutableSortedSet.of(new SizeImpl(1, 512, 10, ImmutableSet.<Architecture> of(
|
||||||
|
Architecture.X86_32, Architecture.X86_64)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Set<? extends VCloudTemplate> provideTemplates(VCloudClient client,
|
||||||
|
Set<? extends Image> images, SortedSet<? extends Size> sizes, LogHolder holder) {
|
||||||
|
Set<VCloudTemplate> templates = Sets.newHashSet();
|
||||||
|
holder.logger.debug(">> generating templates");
|
||||||
|
String vDC = client.getDefaultVDC().getId();
|
||||||
|
for (Size size : sizes) {
|
||||||
|
for (Image image : images) {
|
||||||
|
templates.add(new VCloudTemplate(client, images, sizes, vDC, size, image
|
||||||
|
.getOperatingSystem(), image));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
holder.logger.debug("<< templates(%d)", templates.size());
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.vcloud.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
|
import org.jclouds.vcloud.VCloudClient;
|
||||||
|
import org.jclouds.vcloud.VCloudPropertiesBuilder;
|
||||||
|
import org.jclouds.vcloud.domain.ResourceType;
|
||||||
|
import org.jclouds.vcloud.domain.VApp;
|
||||||
|
import org.jclouds.vcloud.domain.VAppStatus;
|
||||||
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.CaseFormat;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.internal.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code VCloudClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", enabled = true, sequential = true, testName = "vcloud.VCloudClientLiveTest")
|
||||||
|
public class VCloudComputeClientLiveTest {
|
||||||
|
protected String service;
|
||||||
|
protected VCloudComputeClient computeClient;
|
||||||
|
protected VCloudClient client;
|
||||||
|
|
||||||
|
protected String id;
|
||||||
|
protected InetAddress publicAddress;
|
||||||
|
protected String templateId;
|
||||||
|
|
||||||
|
public static class Expectation {
|
||||||
|
final long hardDisk;
|
||||||
|
final String os;
|
||||||
|
|
||||||
|
public Expectation(long hardDisk, String os) {
|
||||||
|
this.hardDisk = hardDisk;
|
||||||
|
this.os = os;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<OperatingSystem, Expectation> expectationMap;
|
||||||
|
|
||||||
|
protected Predicate<InetAddress> addressTester;
|
||||||
|
|
||||||
|
@Test(enabled = true)
|
||||||
|
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
|
IOException {
|
||||||
|
OperatingSystem toTest = OperatingSystem.CENTOS;
|
||||||
|
|
||||||
|
String serverName = getCompatibleServerName(toTest);
|
||||||
|
int processorCount = 1;
|
||||||
|
int memory = 512;
|
||||||
|
long disk = 10 * 1025 * 1024;
|
||||||
|
Map<String, String> properties = ImmutableMap.of("foo", "bar");
|
||||||
|
|
||||||
|
id = computeClient.start(client.getDefaultVDC().getId(), serverName, templateId,
|
||||||
|
processorCount, memory, disk, properties).get("id");
|
||||||
|
Expectation expectation = expectationMap.get(toTest);
|
||||||
|
|
||||||
|
VApp vApp = client.getVApp(id);
|
||||||
|
verifyConfigurationOfVApp(vApp, serverName, expectation.os, processorCount, memory,
|
||||||
|
expectation.hardDisk);
|
||||||
|
assertEquals(vApp.getStatus(), VAppStatus.ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCompatibleServerName(OperatingSystem toTest) {
|
||||||
|
String serverName = CaseFormat.UPPER_UNDERSCORE
|
||||||
|
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
|
||||||
|
toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
|
||||||
|
return serverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testPowerOn", enabled = true)
|
||||||
|
public void testGetPublicAddresses() {
|
||||||
|
publicAddress = Iterables.getLast(computeClient.getPublicAddresses(id));
|
||||||
|
assert !addressTester.apply(publicAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyConfigurationOfVApp(VApp vApp, String serverName, String expectedOs,
|
||||||
|
int processorCount, int memory, long hardDisk) {
|
||||||
|
// assertEquals(vApp.getName(), serverName);
|
||||||
|
// assertEquals(vApp.getOperatingSystemDescription(), expectedOs);
|
||||||
|
assertEquals(
|
||||||
|
Iterables.getOnlyElement(
|
||||||
|
vApp.getResourceAllocationByType().get(ResourceType.PROCESSOR))
|
||||||
|
.getVirtualQuantity(), processorCount);
|
||||||
|
assertEquals(Iterables.getOnlyElement(
|
||||||
|
vApp.getResourceAllocationByType().get(ResourceType.SCSI_CONTROLLER))
|
||||||
|
.getVirtualQuantity(), 1);
|
||||||
|
assertEquals(Iterables.getOnlyElement(
|
||||||
|
vApp.getResourceAllocationByType().get(ResourceType.MEMORY)).getVirtualQuantity(),
|
||||||
|
memory);
|
||||||
|
assertEquals(Iterables.getOnlyElement(
|
||||||
|
vApp.getResourceAllocationByType().get(ResourceType.DISK_DRIVE))
|
||||||
|
.getVirtualQuantity(), hardDisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterTest
|
||||||
|
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
if (id != null)
|
||||||
|
computeClient.stop(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeGroups(groups = { "live" })
|
||||||
|
public void setupClient() {
|
||||||
|
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||||
|
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||||
|
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),
|
||||||
|
"jclouds.test.endpoint");
|
||||||
|
Injector injector = new VCloudComputeServiceContextBuilder(new VCloudPropertiesBuilder(
|
||||||
|
URI.create(endpoint), account, key).build()).withModules(new Log4JLoggingModule(),
|
||||||
|
new JschSshClientModule()).buildInjector();
|
||||||
|
computeClient = injector.getInstance(VCloudComputeClient.class);
|
||||||
|
client = injector.getInstance(VCloudClient.class);
|
||||||
|
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
|
||||||
|
}));
|
||||||
|
expectationMap = ImmutableMap.<OperatingSystem, Expectation> builder().put(
|
||||||
|
OperatingSystem.CENTOS,
|
||||||
|
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).build();
|
||||||
|
service = "vcloudtest";
|
||||||
|
templateId = "3";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue