Issue 243 revise compute api for better support of single nodes and flexible aggregate commands

This commit is contained in:
Adrian Cole 2010-05-13 17:54:04 -07:00
parent b6189457d5
commit 20c282c8bc
25 changed files with 426 additions and 378 deletions

View File

@ -22,9 +22,9 @@ import static org.jclouds.util.Utils.checkNotEmpty;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
@ -32,7 +32,7 @@ import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule.GetRegionFromNodeOrDefault;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule.GetRegionFromLocation;
import org.jclouds.aws.ec2.compute.domain.RegionAndName;
import org.jclouds.aws.ec2.compute.domain.RegionNameAndIngressRules;
import org.jclouds.aws.ec2.domain.KeyPair;
@ -50,9 +50,8 @@ import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.domain.Location;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.base.Predicate;
import com.google.common.collect.Maps;
/**
* @author Adrian Cole
@ -60,7 +59,7 @@ import com.google.common.collect.Sets;
@Singleton
public class EC2ComputeService extends BaseComputeService {
private final EC2Client ec2Client;
private final GetRegionFromNodeOrDefault getRegionFromNodeOrDefault;
private final GetRegionFromLocation getRegionFromLocation;
private final Map<RegionAndName, KeyPair> credentialsMap;
private final Map<RegionAndName, String> securityGroupMap;
@ -73,14 +72,13 @@ public class EC2ComputeService extends BaseComputeService {
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
Provider<TemplateBuilder> templateBuilderProvider, ComputeUtils utils,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
GetRegionFromNodeOrDefault getRegionFromNodeOrDefault,
Map<RegionAndName, KeyPair> credentialsMap,
Map<RegionAndName, String> securityGroupMap) {
GetRegionFromLocation getRegionFromLocation,
Map<RegionAndName, KeyPair> credentialsMap, Map<RegionAndName, String> securityGroupMap) {
super(context, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
templateBuilderProvider, utils, executor);
this.ec2Client = ec2Client;
this.getRegionFromNodeOrDefault = getRegionFromNodeOrDefault;
this.getRegionFromLocation = getRegionFromLocation;
this.credentialsMap = credentialsMap;
this.securityGroupMap = securityGroupMap;
}
@ -110,18 +108,18 @@ public class EC2ComputeService extends BaseComputeService {
}
@Override
public void destroyNodesWithTag(String tag) {
super.destroyNodesWithTag(tag);
Set<String> regions = Sets.newHashSet(Iterables.transform(listNodesWithTag(tag),
new Function<NodeMetadata, String>() {
@Override
public String apply(@Nullable NodeMetadata nodeMetadata) {
return getRegionFromNodeOrDefault.apply(nodeMetadata);
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
Set<? extends NodeMetadata> deadOnes = super.destroyNodesMatching(filter);
Map<String, String> regionTags = Maps.newHashMap();
for (NodeMetadata nodeMetadata : deadOnes) {
if (nodeMetadata.getTag() != null)
regionTags.put(getRegionFromLocation.apply(nodeMetadata.getLocation()), nodeMetadata
.getTag());
}
}));
for (String region : regions) {
deleteKeyPair(region, tag);
deleteSecurityGroup(region, tag);
for (Entry<String, String> regionTag : regionTags.entrySet()) {
deleteKeyPair(regionTag.getKey(), regionTag.getValue());
deleteSecurityGroup(regionTag.getKey(), regionTag.getValue());
}
return deadOnes;
}
}

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.aws.ec2.compute.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy;
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
@ -64,8 +65,8 @@ import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -142,6 +143,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
return template.architecture(Architecture.X86_32).osFamily(UBUNTU);
}
// TODO make this more efficient for listNodes(); currently RunningInstanceToNodeMetadata is slow
// due to image parsing; consider using MapMaker. computing map
@Singleton
public static class EC2ListNodesStrategy implements ListNodesStrategy {
private final InstanceClient client;
@ -155,21 +158,25 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
}
@Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) {
public Iterable<? extends ComputeMetadata> list() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
Set<NodeMetadata> nodes = Sets.newHashSet();
for (String region : ImmutableSet.of(Region.US_EAST_1, Region.US_WEST_1, Region.EU_WEST_1)) {
Iterables.addAll(nodes, Iterables.transform(Iterables.concat(client
.describeInstancesInRegion(region)), runningInstanceToNodeMetadata));
}
return nodes;
return Iterables.filter(nodes, filter);
}
}
@Singleton
public static class GetRegionFromNodeOrDefault implements Function<ComputeMetadata, String> {
public String apply(ComputeMetadata node) {
Location location = node.getLocation();
public static class GetRegionFromLocation implements Function<Location, String> {
public String apply(Location location) {
String region = location.getScope() == LocationScope.REGION ? location.getId() : location
.getParent().getId();
return region;
@ -181,22 +188,22 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
private final InstanceClient client;
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
private final GetRegionFromNodeOrDefault getRegionFromNodeOrDefault;
private final GetRegionFromLocation getRegionFromLocation;
@Inject
protected EC2GetNodeMetadataStrategy(InstanceClient client,
GetRegionFromNodeOrDefault getRegionFromNodeOrDefault,
GetRegionFromLocation getRegionFromLocation,
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
this.client = client;
this.getRegionFromNodeOrDefault = getRegionFromNodeOrDefault;
this.getRegionFromLocation = getRegionFromLocation;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
String region = getRegionFromNodeOrDefault.apply(node);
public NodeMetadata execute(Location location, String id) {
String region = getRegionFromLocation.apply(checkNotNull(location, "location"));
RunningInstance runningInstance = Iterables.getOnlyElement(getAllRunningInstancesInRegion(
client, region, node.getId()));
client, region, checkNotNull(id, "id")));
return runningInstanceToNodeMetadata.apply(runningInstance);
}
@ -210,19 +217,19 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
@Singleton
public static class EC2RebootNodeStrategy implements RebootNodeStrategy {
private final InstanceClient client;
private final GetRegionFromNodeOrDefault getRegionFromNodeOrDefault;
private final GetRegionFromLocation getRegionFromLocation;
@Inject
protected EC2RebootNodeStrategy(InstanceClient client,
GetRegionFromNodeOrDefault getRegionFromNodeOrDefault) {
GetRegionFromLocation getRegionFromLocation) {
this.client = client;
this.getRegionFromNodeOrDefault = getRegionFromNodeOrDefault;
this.getRegionFromLocation = getRegionFromLocation;
}
@Override
public boolean execute(ComputeMetadata node) {
String region = getRegionFromNodeOrDefault.apply(node);
client.rebootInstancesInRegion(region, node.getId());
public boolean execute(Location location, String id) {
String region = getRegionFromLocation.apply(location);
client.rebootInstancesInRegion(region, id);
return true;
}

View File

@ -25,13 +25,12 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule.GetRegionFromNodeOrDefault;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule.GetRegionFromLocation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
@ -48,29 +47,25 @@ public class EC2DestroyNodeStrategy implements DestroyNodeStrategy {
protected Logger logger = Logger.NULL;
protected final EC2Client ec2Client;
protected final Predicate<RunningInstance> instanceStateTerminated;
protected final GetRegionFromNodeOrDefault getRegionFromNodeOrDefault;
protected final GetRegionFromLocation getRegionFromLocation;
protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
@Inject
protected EC2DestroyNodeStrategy(EC2Client ec2Client,
@Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated,
GetRegionFromNodeOrDefault getRegionFromNodeOrDefault,
GetRegionFromLocation getRegionFromLocation,
GetNodeMetadataStrategy getNodeMetadataStrategy) {
this.ec2Client = ec2Client;
this.instanceStateTerminated = instanceStateTerminated;
this.getRegionFromNodeOrDefault = getRegionFromNodeOrDefault;
this.getRegionFromLocation = getRegionFromLocation;
this.getNodeMetadataStrategy = getNodeMetadataStrategy;
}
@Override
public boolean execute(ComputeMetadata metadata) {
NodeMetadata node = metadata instanceof NodeMetadata ? NodeMetadata.class.cast(metadata)
: getNodeMetadataStrategy.execute(metadata);
String region = getRegionFromNodeOrDefault.apply(node);
ec2Client.getInstanceServices().terminateInstancesInRegion(region, node.getId());
public boolean execute(Location location, String id) {
String region = getRegionFromLocation.apply(location);
ec2Client.getInstanceServices().terminateInstancesInRegion(region, id);
return instanceStateTerminated.apply(Iterables.getOnlyElement(Iterables.concat(ec2Client
.getInstanceServices().describeInstancesInRegion(region, node.getId()))));
.getInstanceServices().describeInstancesInRegion(region, id))));
}
}

View File

@ -37,6 +37,7 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Credentials;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass;
@ -138,7 +139,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
result.getKeyMaterial()));
} finally {
client.destroyNodesWithTag(tag);
client.destroyNodesMatching(NodePredicates.withTag(tag));
if (startedId != null) {
// ensure we didn't delete these resources!
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1);
@ -190,7 +191,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assert group.getIpPermissions().size() == 0 : group;
} finally {
client.destroyNodesWithTag(tag);
client.destroyNodesMatching(NodePredicates.withTag(tag));
if (startedId != null) {
// ensure we didn't delete these resources!
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1);

View File

@ -60,7 +60,9 @@ See http://code.google.com/p/jclouds for details."
[org.jclouds.compute.domain
Template TemplateBuilder ComputeMetadata NodeMetadata Size OsFamily
Image Architecture]
[org.jclouds.compute.options TemplateOptions GetNodesOptions]
[org.jclouds.compute.options TemplateOptions]
[org.jclouds.compute.predicates
NodePredicates]
[com.google.common.collect ImmutableSet]))
(try
@ -121,26 +123,12 @@ See http://code.google.com/p/jclouds for details."
(defn nodes-with-tag
[#^String tag #^ComputeService compute]
(seq (.listNodesWithTag compute tag)))
(def #^{:private true} list-nodes-map
{ :with-details #(when %2 (.withDetails %1)) })
(seq (.listNodesMatching(compute (NodePredicates/withTag tag)))))
(defn nodes
"Retrieve the existing nodes for the compute context.
Options are:
:with-details true"
([] (nodes *compute*))
([compute-or-tag & options]
(if (compute-service? compute-or-tag)
(let [options (apply hash-map options)
list-nodes-options (reduce
(fn [lno [k v]]
((list-nodes-map k) lno v)
lno)
(GetNodesOptions.) options)]
(seq (.listNodes compute-or-tag list-nodes-options)))
(nodes-with-tag compute-or-tag *compute*))))
"Retrieve the existing nodes for the compute context."
[#^ComputeService compute]
(seq (.listNodes compute)))
(defn images
"Retrieve the available images for the compute context."
@ -219,33 +207,33 @@ See http://code.google.com/p/jclouds for details."
(defn #^NodeMetadata node-details
"Retrieve the node metadata."
([node] (node-details node *compute*))
([node #^ComputeService compute]
(.getNodeMetadata compute node )))
([location id] (node-details location id *compute*))
([#^Location location id #^ComputeService compute]
(.getNodeMetadata compute location id)))
(defn reboot-nodes
(defn reboot-nodes-with-tag
"Reboot all the nodes with the given tag."
([tag] (reboot-nodes tag *compute*))
([tag] (reboot-nodes-with-tag tag *compute*))
([#^String tag #^ComputeService compute]
(.rebootNodesWithTag compute tag )))
(.rebootNodesMatching(compute (NodePredicates/withTag tag)))))
(defn reboot-node
"Reboot a given node."
([node] (reboot-node node *compute*))
([#^ComputeMetadata node #^ComputeService compute]
(.rebootNode compute node )))
([location id] (reboot-node location id *compute*))
([#^Location location id #^ComputeService compute]
(.rebootNode compute location id)))
(defn destroy-nodes
(defn destroy-nodes-with-tag
"Destroy all the nodes with the given tag."
([tag] (destroy-nodes tag *compute*))
([tag] (destroy-nodes-with-tag tag *compute*))
([#^String tag #^ComputeService compute]
(.destroyNodesWithTag compute tag )))
(seq (.destroyNodesMatching(compute (NodePredicates/withTag tag))))))
(defn destroy-node
"Destroy a given node."
([node] (destroy-node node *compute*))
([#^ComputeMetadata node #^ComputeServiceContext compute]
(.destroyNode compute node)))
([location id] (destroy-node location id *compute*))
([#^Location location id #^ComputeService compute]
(.destroyNode compute location id)))
(defmacro state-predicate [node state]
`(= (.getState ~node)
@ -407,4 +395,3 @@ There are many options to use for the default template
(if next
(recur next remaining)))))
(.build builder)))

View File

@ -28,7 +28,6 @@ import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.Location;
import org.jclouds.ssh.ExecResponse;
@ -80,12 +79,6 @@ public interface ComputeService {
*/
Set<? extends ComputeMetadata> listNodes();
/**
* all nodes available to the current user by id. If possible, the returned set will include
* {@link NodeMetadata} objects.
*/
Set<? extends ComputeMetadata> listNodes(GetNodesOptions options);
/**
* The list locations command returns all the valid locations for nodes. A location has a scope,
* which is typically region or zone. A region is a general area, like eu-west, where a zone is
@ -136,66 +129,70 @@ public interface ComputeService {
* destroy the node. If it is the only node in a tag set, the dependent resources will also be
* destroyed.
*/
void destroyNode(ComputeMetadata node);
void destroyNode(Location location, String id);
/**
* nodes which are tagged are treated as a logical set. Using the delete command, you can save
* nodes matching the filter are treated as a logical set. Using the delete command, you can save
* time by removing the nodes in parallel. When the last node in a set is destroyed, any indirect
* resources it uses, such as keypairs, are also destroyed.
*
* @return list of nodes destroyed
*/
void destroyNodesWithTag(String tag);
Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter);
/**
* reboot the node.
*/
void rebootNode(ComputeMetadata node);
void rebootNode(Location location, String id);
/**
* nodes which are tagged are treated as a logical set. Using this command, you can save time by
* rebooting the nodes in parallel.
* nodes matching the filter are treated as a logical set. Using this command, you can save time
* by rebooting the nodes in parallel.
*/
void rebootNodesWithTag(String tag);
void rebootNodesMatching(Predicate<NodeMetadata> filter);
/**
* Find a node by its id
*/
NodeMetadata getNodeMetadata(ComputeMetadata node);
NodeMetadata getNodeMetadata(Location location, String id);
/**
* get all nodes matching the tag.
* get all nodes including details such as image and ip addresses even if it incurs extra
* requests to the service.
*
* @param tag
* @param filter
* how to select the nodes you are interested in details on.
*/
Set<? extends NodeMetadata> listNodesWithTag(String tag);
Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter);
/**
* Runs the script without any additional options
*
* @see #runScriptOnNodesMatching(Predicate, byte[], org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
* @see #runScriptOnNodesMatching(Predicate, byte[],
* org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
*/
Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript)
throws RunScriptOnNodesException;
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
Predicate<NodeMetadata> filter, byte[] runScript) throws RunScriptOnNodesException;
/**
* Run the script on all nodes with the specific tag.
*
* @param filter
* Predicate-based filter to define on which nodes the script is to be
* executed
* Predicate-based filter to define on which nodes the script is to be executed
* @param runScript
* script to run in byte format. If the script is a string, use
* {@link String#getBytes()} to retrieve the bytes
* @param options
* nullable options to how to run the script, whether to override credentials
* @return map with node identifiers and corresponding responses
* @throws RunScriptOnNodesException if anything goes wrong during script execution
* @throws RunScriptOnNodesException
* if anything goes wrong during script execution
*
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
*/
Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript,
RunScriptOptions options) throws RunScriptOnNodesException;
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
Predicate<NodeMetadata> filter, byte[] runScript, RunScriptOptions options)
throws RunScriptOnNodesException;
}

View File

@ -25,11 +25,9 @@ package org.jclouds.compute.internal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.predicates.NodePredicates.withTag;
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
import static org.jclouds.concurrent.ConcurrentUtils.makeListenable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
@ -48,13 +46,11 @@ import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.RunScriptOnNodesException;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -74,7 +70,6 @@ import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListenableFuture;
@ -102,7 +97,6 @@ public class BaseComputeService implements ComputeService {
protected final Provider<TemplateBuilder> templateBuilderProvider;
protected final ComputeUtils utils;
protected final ExecutorService executor;
protected final ComputeMetadataToNodeMetadata computeMetadataToNodeMetadata;
@Inject
protected BaseComputeService(ComputeServiceContext context,
@ -128,7 +122,6 @@ public class BaseComputeService implements ComputeService {
"templateBuilderProvider");
this.utils = checkNotNull(utils, "utils");
this.executor = checkNotNull(executor, "executor");
this.computeMetadataToNodeMetadata = new ComputeMetadataToNodeMetadata();
}
@Override
@ -157,27 +150,24 @@ public class BaseComputeService implements ComputeService {
}
@Override
public void destroyNode(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
logger.debug(">> destroying node(%s)", node.getId());
boolean successful = destroyNodeStrategy.execute(node);
logger.debug("<< destroyed node(%s) success(%s)", node.getId(), successful);
public void destroyNode(Location location, String id) {
checkNotNull(location, "location");
checkNotNull(id, "id");
logger.debug(">> destroying node(%s/%s)", location.getId(), id);
boolean successful = destroyNodeStrategy.execute(location, id);
logger.debug("<< destroyed node(%s/%s) success(%s)", location.getId(), id, successful);
}
@Override
public void destroyNodesWithTag(String tag) { // TODO parallel
logger.debug(">> destroying nodes by tag(%s)", tag);
Iterable<? extends NodeMetadata> nodesToDestroy = Iterables.filter(doListNodesWithTag(tag),
Predicates.not(NodePredicates.TERMINATED));
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> destroying nodes matching(%s)", filter);
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
final List<NodeMetadata> destroyedNodes = Lists.newArrayList();
for (final NodeMetadata node : nodesToDestroy) {
final Set<NodeMetadata> destroyedNodes = Sets.newLinkedHashSet();
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
destroyNode(node);
destroyNode(node.getLocation(), node.getId());
destroyedNodes.add(node);
return null;
}
@ -185,49 +175,31 @@ public class BaseComputeService implements ComputeService {
}
awaitCompletion(responses, executor, null, logger, "destroying nodes");
logger.debug("<< destroyed");
return destroyedNodes;
}
private Iterable<? extends NodeMetadata> nodesMatchingFilterAndNotTerminated(
Predicate<NodeMetadata> filter) {
return Iterables.filter(detailsOnAllNodes(), Predicates.and(filter, Predicates
.not(NodePredicates.TERMINATED)));
}
@Override
public Set<? extends ComputeMetadata> listNodes() {
return listNodes(null);
}
@Override
public Set<? extends ComputeMetadata> listNodes(GetNodesOptions options) {
logger.debug(">> listing servers");
if (options == null) {
options = GetNodesOptions.NONE;
}
Set<? extends ComputeMetadata> set = Sets
.newLinkedHashSet(listNodesStrategy.execute(options));
logger.debug(">> listing nodes");
Set<? extends ComputeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy.list());
logger.debug("<< list(%d)", set.size());
return set;
}
/**
* If the result of {@link ListNodesStrategy#execute} is a set of nodes, then return them.
* Otherwise iteratively call {@link #getNodeMetadata}
*/
protected Set<? extends NodeMetadata> doListNodesWithTag(final String tag) {
return Sets.newHashSet(Iterables.filter(Iterables.transform(listNodesStrategy
.execute(GetNodesOptions.NONE), computeMetadataToNodeMetadata), withTag(tag)));
}
class ComputeMetadataToNodeMetadata implements Function<ComputeMetadata, NodeMetadata> {
@Override
public NodeMetadata apply(ComputeMetadata from) {
return from instanceof NodeMetadata ? NodeMetadata.class.cast(from)
: getNodeMetadata(from);
}
}
@Override
public Set<? extends NodeMetadata> listNodesWithTag(String tag) {
logger.debug(">> listing nodes by tag(%s)", tag);
Set<? extends NodeMetadata> nodes = doListNodesWithTag(tag);
logger.debug("<< list(%d)", nodes.size());
return nodes;
public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
checkNotNull(filter, "filter");
logger.debug(">> listing node details matching(%s)", filter);
Set<? extends NodeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy
.listDetailsOnNodesMatching(filter));
logger.debug("<< list(%d)", set.size());
return set;
}
@Override
@ -251,33 +223,31 @@ public class BaseComputeService implements ComputeService {
}
@Override
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
return getNodeMetadataStrategy.execute(node);
public NodeMetadata getNodeMetadata(Location location, String id) {
checkNotNull(location, "location");
checkNotNull(id, "id");
return getNodeMetadataStrategy.execute(location, id);
}
@Override
public void rebootNode(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
checkNotNull(node.getId(), "node.id");
logger.debug(">> rebooting node(%s)", node.getId());
boolean successful = rebootNodeStrategy.execute(node);
logger.debug("<< rebooted node(%s) success(%s)", node.getId(), successful);
public void rebootNode(Location location, String id) {
checkNotNull(location, "location");
checkNotNull(id, "id");
logger.debug(">> rebooting node(%s/%s)", location.getId(), id);
boolean successful = rebootNodeStrategy.execute(location, id);
logger.debug("<< rebooted node(%s/%s) success(%s)", location.getId(), id, successful);
}
@Override
public void rebootNodesWithTag(String tag) { // TODO parallel
logger.debug(">> rebooting nodes by tag(%s)", tag);
Iterable<? extends NodeMetadata> nodesToReboot = Iterables.filter(doListNodesWithTag(tag),
Predicates.not(NodePredicates.TERMINATED));
public void rebootNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> rebooting nodes matching(%s)", filter);
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
for (final NodeMetadata node : nodesToReboot) {
for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
rebootNode(node);
rebootNode(node.getLocation(), node.getId());
return null;
}
}), executor));
@ -290,10 +260,11 @@ public class BaseComputeService implements ComputeService {
* @throws RunScriptOnNodesException
* @see #runScriptOnNodesMatching(Predicate, byte[],
* org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
*/
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
byte[] runScript) throws RunScriptOnNodesException {
@Override
public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
Predicate<NodeMetadata> filter, byte[] runScript) throws RunScriptOnNodesException {
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
}
@ -311,12 +282,13 @@ public class BaseComputeService implements ComputeService {
* @throws RunScriptOnNodesException
* if anything goes wrong during script execution
*
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
*/
@Override
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
final byte[] runScript, @Nullable final RunScriptOptions options)
throws RunScriptOnNodesException {
Iterable<? extends NodeMetadata> nodes = verifyParametersAndGetNodes(filter, runScript,
Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(filter, runScript,
(options != null) ? options : RunScriptOptions.NONE);
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap();
@ -363,14 +335,14 @@ public class BaseComputeService implements ComputeService {
}
private Iterable<? extends NodeMetadata> verifyParametersAndGetNodes(
private Iterable<? extends NodeMetadata> verifyParametersAndListNodes(
Predicate<NodeMetadata> filter, byte[] runScript, final RunScriptOptions options) {
checkNotNull(filter, "Filter must be provided");
checkNotNull(runScript,
"The script (represented by bytes array - use \"script\".getBytes() must be provided");
checkNotNull(options, "options");
Iterable<? extends NodeMetadata> nodes = Iterables.filter(Iterables.transform(listNodes(),
computeMetadataToNodeMetadata), filter);
Iterable<? extends NodeMetadata> nodes = Iterables.filter(detailsOnAllNodes(), filter);
return Iterables.transform(nodes, new Function<NodeMetadata, NodeMetadata>() {
@ -397,4 +369,8 @@ public class BaseComputeService implements ComputeService {
}
});
}
private Iterable<? extends NodeMetadata> detailsOnAllNodes() {
return listNodesStrategy.listDetailsOnNodesMatching(NodePredicates.all());
}
}

View File

@ -1,80 +0,0 @@
package org.jclouds.compute.options;
/**
* @author Ivan Meredith
*/
public class GetNodesOptions implements Cloneable {
public static final ImmutableGetNodesOptions NONE = new ImmutableGetNodesOptions(
new GetNodesOptions());
private boolean detailed;
public GetNodesOptions() {
}
GetNodesOptions(boolean detailed) {
this.detailed = detailed;
}
public static class ImmutableGetNodesOptions extends GetNodesOptions {
private final GetNodesOptions delegate;
public ImmutableGetNodesOptions(GetNodesOptions delegate) {
this.delegate = delegate;
}
@Override
public boolean isDetailed() {
return delegate.isDetailed();
}
@Override
public GetNodesOptions clone() {
return delegate.clone();
}
@Override
public String toString() {
return delegate.toString();
}
}
public boolean isDetailed() {
return detailed;
}
/**
* populate each result with detailed such as metadata even if it incurs extra requests to the
* service.
*/
public GetNodesOptions withDetails() {
this.detailed = true;
return this;
}
public static class Builder {
/**
* @see GetNodesOptions#withDetails()
*/
public static GetNodesOptions withDetails() {
GetNodesOptions options = new GetNodesOptions();
return options.withDetails();
}
}
@Override
public GetNodesOptions clone() {
return new GetNodesOptions(detailed);
}
@Override
public String toString() {
return "[detailed=" + detailed + "]";
}
}

View File

@ -35,7 +35,43 @@ public class RunScriptOptions {
* <li>run the script as root (versus running with current privileges)</li>
* </ul>
*/
public static final RunScriptOptions NONE = new RunScriptOptions();
public static final RunScriptOptions NONE = new ImmutableRunScriptOptions(new RunScriptOptions());
public static class ImmutableRunScriptOptions extends RunScriptOptions {
private final RunScriptOptions delegate;
public ImmutableRunScriptOptions(RunScriptOptions delegate) {
this.delegate = delegate;
}
@Override
public String toString() {
return delegate.toString();
}
@Override
public Credentials getOverrideCredentials() {
return delegate.getOverrideCredentials();
}
@Override
public boolean isRunAsRoot() {
return delegate.isRunAsRoot();
}
@Override
public RunScriptOptions runAsRoot(boolean runAsRoot) {
throw new IllegalArgumentException("runAsRoot is immutable");
}
@Override
public RunScriptOptions withOverridingCredentials(Credentials overridingCredentials) {
throw new IllegalArgumentException("overridingCredentials is immutable");
}
}
private Credentials overridingCredentials;
private boolean runAsRoot = true;

View File

@ -43,6 +43,90 @@ public class TemplateOptions {
public static final TemplateOptions NONE = new TemplateOptions();
public static class ImmutableTemplateOptions extends TemplateOptions {
private final TemplateOptions delegate;
public ImmutableTemplateOptions(TemplateOptions delegate) {
this.delegate = delegate;
}
@Override
public String toString() {
return delegate.toString();
}
@Override
public <T extends TemplateOptions> T as(Class<T> clazz) {
return delegate.as(clazz);
}
@Override
public TemplateOptions authorizePublicKey(String publicKey) {
return delegate.authorizePublicKey(publicKey);
}
@Override
public TemplateOptions blockOnPort(int port, int seconds) {
throw new IllegalArgumentException("port, seconds are immutable");
}
@Override
public int[] getInboundPorts() {
return delegate.getInboundPorts();
}
@Override
public int getPort() {
return delegate.getPort();
}
@Override
public String getPrivateKey() {
return delegate.getPrivateKey();
}
@Override
public String getPublicKey() {
return delegate.getPublicKey();
}
@Override
public byte[] getRunScript() {
return delegate.getRunScript();
}
@Override
public int getSeconds() {
return delegate.getSeconds();
}
@Override
public TemplateOptions inboundPorts(int... ports) {
throw new IllegalArgumentException("ports is immutable");
}
@Override
public TemplateOptions installPrivateKey(String privateKey) {
throw new IllegalArgumentException("privateKey is immutable");
}
@Override
public boolean isIncludeMetadata() {
return delegate.isIncludeMetadata();
}
@Override
public TemplateOptions runScript(byte[] script) {
throw new IllegalArgumentException("withMetadata is immutable");
}
@Override
public TemplateOptions withMetadata() {
throw new IllegalArgumentException("withMetadata is immutable");
}
}
protected int[] inboundPorts = new int[] { 22 };
protected byte[] script;

View File

@ -30,6 +30,7 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Sets;
/**
@ -65,6 +66,13 @@ public class NodePredicates {
};
}
/**
* return everything.
*/
public static Predicate<ComputeMetadata> all() {
return Predicates.<ComputeMetadata> alwaysTrue();
}
/**
* Return nodes with specified tag. Note: returns all nodes, regardless of the state.
*
@ -94,7 +102,7 @@ public class NodePredicates {
* tag to match the items
* @return predicate
*/
public static Predicate<NodeMetadata> activeWithTag(final String tag) {
public static Predicate<NodeMetadata> runningWithTag(final String tag) {
checkNotEmpty(tag, "Tag must be defined");
return new Predicate<NodeMetadata>() {
@Override
@ -105,7 +113,7 @@ public class NodePredicates {
@Override
public String toString() {
return "activeWithTag(" + tag + ")";
return "runningWithTag(" + tag + ")";
}
};
}

View File

@ -19,7 +19,7 @@
package org.jclouds.compute.strategy;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.domain.Location;
/**
* terminates the node and blocks until it is no longer visible or in the state TERMINATED. If this
@ -29,6 +29,6 @@ import org.jclouds.compute.domain.ComputeMetadata;
*/
public interface DestroyNodeStrategy {
boolean execute(ComputeMetadata node);
boolean execute(Location location, String id);
}

View File

@ -19,8 +19,8 @@
package org.jclouds.compute.strategy;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Location;
/**
* returns all details associated to the node below.
@ -29,6 +29,6 @@ import org.jclouds.compute.domain.NodeMetadata;
*/
public interface GetNodeMetadataStrategy {
NodeMetadata execute(ComputeMetadata node);
NodeMetadata execute(Location location, String id);
}

View File

@ -20,7 +20,9 @@
package org.jclouds.compute.strategy;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.domain.NodeMetadata;
import com.google.common.base.Predicate;
/**
*
@ -28,5 +30,8 @@ import org.jclouds.compute.options.GetNodesOptions;
*/
public interface ListNodesStrategy {
Iterable<? extends ComputeMetadata> execute(GetNodesOptions options);
Iterable<? extends ComputeMetadata> list();
Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter);
}

View File

@ -19,7 +19,7 @@
package org.jclouds.compute.strategy;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.domain.Location;
/**
* Reboots a node unless it is in the state TERMINATED.
@ -28,6 +28,6 @@ import org.jclouds.compute.domain.ComputeMetadata;
*/
public interface RebootNodeStrategy {
boolean execute(ComputeMetadata node);
boolean execute(Location location, String id);
}

View File

@ -36,7 +36,6 @@ import org.jclouds.Constants;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy;
@ -123,8 +122,7 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd
*/
protected Set<String> getNextNames(final String tag, final Template template, int count) {
Set<String> names = Sets.newHashSet();
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy
.execute(GetNodesOptions.NONE);
Iterable<? extends ComputeMetadata> currentNodes = listNodesStrategy.list();
int maxTries = 100;
int currentTries = 0;
while (names.size() < count && currentTries++ < maxTries) {

View File

@ -44,7 +44,6 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.NodePredicates;
@ -66,7 +65,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Charsets;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
@ -172,7 +170,7 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testTemplateMatch")
public void testCreateTwoNodesWithRunScript() throws Exception {
try {
client.destroyNodesWithTag(tag);
client.destroyNodesMatching(NodePredicates.withTag(tag));
} catch (HttpResponseException e) {
// TODO hosting.com throws 400 when we try to delete a vApp
} catch (NoSuchElementException e) {
@ -236,8 +234,9 @@ public abstract class BaseComputeServiceLiveTest {
assert good.account != null;
try {
Map<NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, simpleTemplate
.getImage().getOsFamily(), new Credentials(good.account, "romeo"));
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag,
simpleTemplate.getImage().getOsFamily(),
new Credentials(good.account, "romeo"));
assert false : "shouldn't pass with a bad password\n" + responses;
} catch (RunScriptOnNodesException e) {
assert Throwables.getRootCause(e).getMessage().contains("Auth fail") : e;
@ -248,25 +247,19 @@ public abstract class BaseComputeServiceLiveTest {
checkNodes(nodes, tag);
} finally {
client.destroyNodesWithTag(tag);
client.destroyNodesMatching(NodePredicates.withTag(tag));
}
}
protected Map<NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OsFamily osFamily,
Credentials creds) throws RunScriptOnNodesException {
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag,
OsFamily osFamily, Credentials creds) throws RunScriptOnNodesException {
try {
return client.runScriptOnNodesMatching(new Predicate<NodeMetadata>() {
@Override
public boolean apply(NodeMetadata arg0) {
return arg0.getState() == NodeState.RUNNING && tag.equals(arg0.getTag());
}
}, buildScript(osFamily).getBytes(), RunScriptOptions.Builder
.overrideCredentialsWith(creds));
return client.runScriptOnNodesMatching(NodePredicates.runningWithTag(tag), buildScript(
osFamily).getBytes(), RunScriptOptions.Builder.overrideCredentialsWith(creds));
} catch (SshException e) {
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
System.err.printf("bad credentials: %s:%s for %s%n", creds.account, creds.key, client
.listNodesWithTag(tag));
// System.err.printf("bad credentials: %s:%s for %s%n", creds.account, creds.key, client
// .listNodesDetailsMatching(tag));
}
throw e;
}
@ -326,11 +319,12 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
public void testGet() throws Exception {
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables.filter(client
.listNodesWithTag(tag), Predicates.not(NodePredicates.TERMINATED)));
Set<? extends NodeMetadata> nodes = client.listNodesDetailsMatching(NodePredicates.all());
Set<? extends NodeMetadata> metadataSet = Sets.newHashSet(Iterables.filter(nodes, Predicates
.and(NodePredicates.withTag(tag), Predicates.not(NodePredicates.TERMINATED))));
for (NodeMetadata node : nodes) {
metadataSet.remove(node);
NodeMetadata metadata = client.getNodeMetadata(node);
NodeMetadata metadata = client.getNodeMetadata(node.getLocation(), node.getId());
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getTag(), node.getTag());
assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
@ -345,7 +339,7 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testGet")
public void testReboot() throws Exception {
client.rebootNodesWithTag(tag);// TODO test validation
client.rebootNodesMatching(NodePredicates.withTag(tag));// TODO test validation
testGet();
}
@ -366,7 +360,7 @@ public abstract class BaseComputeServiceLiveTest {
}
public void testGetNodesWithDetails() throws Exception {
for (ComputeMetadata node : client.listNodes(new GetNodesOptions().withDetails())) {
for (NodeMetadata node : client.listNodesDetailsMatching(NodePredicates.all())) {
assert node.getId() != null : node;
assert node.getLocation() != null : node;
assertEquals(node.getType(), ComputeType.NODE);
@ -479,8 +473,9 @@ public abstract class BaseComputeServiceLiveTest {
@AfterTest
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (nodes != null) {
client.destroyNodesWithTag(tag);
for (NodeMetadata node : client.listNodesWithTag(tag)) {
client.destroyNodesMatching(NodePredicates.withTag(tag));
for (NodeMetadata node : Iterables.filter(client.listNodesDetailsMatching(NodePredicates
.all()), NodePredicates.withTag(tag))) {
assert node.getState() == NodeState.TERMINATED : node;
}
}

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.gogrid.compute.config;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OsFamily.CENTOS;
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAULT_DC;
@ -49,7 +50,7 @@ import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -137,9 +138,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
public boolean execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
new Long(id)));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START);
@ -160,11 +161,16 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
}
@Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) {
return Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata);
public Iterable<? extends ComputeMetadata> list() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata), filter);
}
}
@Singleton
@ -180,9 +186,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
public NodeMetadata execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
new Long(checkNotNull(id, "id"))));
return server == null ? null : serverToNodeMetadata.apply(server);
}
}
@ -200,9 +206,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
public boolean execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
new Long(id)));
client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server);
}

View File

@ -53,7 +53,7 @@ import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -142,8 +142,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
}
@Override
public boolean execute(ComputeMetadata node) {
int serverId = Integer.parseInt(node.getId());
public boolean execute(Location location, String id) {
int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place
client.rebootServer(serverId, RebootType.HARD);
Server server = client.getServer(serverId);
@ -165,8 +165,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
}
@Override
public boolean execute(ComputeMetadata node) {
int serverId = Integer.parseInt(node.getId());
public boolean execute(Location location, String id) {
int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place
if (!client.deleteServer(serverId))
return false;
@ -216,11 +216,16 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
}
@Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) {
return Iterables.transform(client.listServers(ListOptions.Builder.withDetails()),
serverToNodeMetadata);
public Iterable<? extends ComputeMetadata> list() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.listServers(ListOptions.Builder
.withDetails()), serverToNodeMetadata), filter);
}
}
@Singleton
@ -237,8 +242,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
int serverId = Integer.parseInt(node.getId());
public NodeMetadata execute(Location location, String id) {
int serverId = Integer.parseInt(id);
Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server);
}

View File

@ -56,7 +56,7 @@ import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -140,8 +140,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
}
@Override
public boolean execute(ComputeMetadata node) {
Long serverId = Long.parseLong(node.getId());
public boolean execute(Location location, String id) {
Long serverId = Long.parseLong(id);
// if false server wasn't around in the first place
return client.restartServer(serverId).getState() == RunningState.RUNNING;
}
@ -161,8 +161,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
}
@Override
public boolean execute(ComputeMetadata node) {
long serverId = Long.parseLong(node.getId());
public boolean execute(Location location, String id) {
long serverId = Long.parseLong(id);
client.destroyServer(serverId);
return serverDestroyed.apply(client.getServer(serverId));
}
@ -220,8 +220,15 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
}
@Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) {
return Iterables.transform(client.getServerList(), serverToNodeMetadata);
public Iterable<? extends ComputeMetadata> list() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.getServerList(), serverToNodeMetadata),
filter);
}
}
@ -240,8 +247,9 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
long serverId = Long.parseLong(node.getId());
public NodeMetadata execute(Location location, String id) {
// TODO location
long serverId = Long.parseLong(id);
Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server);
}

View File

@ -40,11 +40,13 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Location;
import org.jclouds.http.HttpUtils;
import com.google.common.base.CaseFormat;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.inject.Provider;
/**
@ -219,19 +221,21 @@ public class ComputeTask extends Task {
private void destroy(ComputeService computeService) {
log(String.format("destroy tag: %s", nodeElement.getTag()));
computeService.destroyNodesWithTag(nodeElement.getTag());
computeService.destroyNodesMatching(NodePredicates.withTag(nodeElement.getTag()));
}
private void get(ComputeService computeService) {
log(String.format("get tag: %s", nodeElement.getTag()));
for (ComputeMetadata node : computeService.listNodesWithTag(nodeElement.getTag())) {
for (ComputeMetadata node : Iterables.filter(computeService
.listNodesDetailsMatching(NodePredicates.all()), NodePredicates.withTag(nodeElement
.getTag()))) {
logDetails(computeService, node);
}
}
private void logDetails(ComputeService computeService, ComputeMetadata node) {
NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node)
: computeService.getNodeMetadata(node);
: computeService.getNodeMetadata(node.getLocation(), node.getId());
log(String
.format(
" node id=%s, name=%s, tag=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, extra=%s",

View File

@ -18,7 +18,6 @@
*/
package org.jclouds.vcloud.compute.config;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
@ -50,12 +49,12 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -163,8 +162,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
}
@Override
public boolean execute(ComputeMetadata node) {
Task task = client.resetVApp(node.getId());
public boolean execute(Location location, String id) {
Task task = client.resetVApp(id);
return taskTester.apply(task.getId());
}
@ -180,8 +179,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
}
@Override
public boolean execute(ComputeMetadata node) {
computeClient.stop(checkNotNull(node.getId(), "node.id"));
public boolean execute(Location location, String id) {
computeClient.stop(checkNotNull(id, "node.id"));
return true;
}
@ -241,11 +240,31 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
}
@Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) {
public Iterable<ComputeMetadata> list() {
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(convertVAppToComputeMetadata(vdc, resource));
}
}
}
return nodes;
}
private ComputeMetadata convertVAppToComputeMetadata(NamedResource vdc, NamedResource resource) {
Location location = findLocationForResourceInVDC.apply(resource, vdc.getId());
return new ComputeMetadataImpl(ComputeType.NODE, resource.getId(), resource.getName(),
location, null, ImmutableMap.<String, String> of());
}
@Override
public Iterable<NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
Set<NodeMetadata> 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)
&& filter.apply(convertVAppToComputeMetadata(vdc, resource))) {
addVAppToSetRetryingIfNotYetPresent(nodes, vdc, resource);
}
}
@ -254,7 +273,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
}
@VisibleForTesting
void addVAppToSetRetryingIfNotYetPresent(Set<ComputeMetadata> nodes, NamedResource vdc,
void addVAppToSetRetryingIfNotYetPresent(Set<NodeMetadata> nodes, NamedResource vdc,
NamedResource resource) {
NodeMetadata node = null;
int i = 0;
@ -284,11 +303,9 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location").getId(),
checkNotNull(node.getId(), "node.id"));
public NodeMetadata execute(Location location, String id) {
return getNodeMetadataByIdInVDC(checkNotNull(location, "location").getId(), checkNotNull(
id, "node.id"));
}
}

View File

@ -57,6 +57,7 @@ import com.google.common.collect.Iterables;
*/
@Singleton
public class VCloudGetNodeMetadata {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
public Logger logger = Logger.NULL;

View File

@ -48,7 +48,7 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
NodeMetadata allData = client.getNodeMetadata(node);
NodeMetadata allData = client.getNodeMetadata(node.getLocation(), node.getId());
assert allData.getExtra().get("processor/count") != null;
assert allData.getExtra().get("disk_drive/1/kb") != null;
assert allData.getExtra().get("memory/mb") != null;

View File

@ -33,8 +33,8 @@ import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
@ -124,7 +124,7 @@ public class VCloudComputeServiceContextModuleTest {
VCloudListNodesStrategy strategy = new VCloudListNodesStrategy(client, computeClient,
vAppStatusToNodeState, getExtra, findLocationForResourceInVDC, images);
Set<ComputeMetadata> nodes = Sets.newHashSet();
Set<NodeMetadata> nodes = Sets.newHashSet();
NamedResource vdc = new NamedResourceImpl("1", null, null, null);
NamedResource resource = new NamedResourceImpl("10", null, null, null);