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

View File

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

View File

@ -25,13 +25,12 @@ import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2Client; 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.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.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
@ -48,29 +47,25 @@ public class EC2DestroyNodeStrategy implements DestroyNodeStrategy {
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final EC2Client ec2Client; protected final EC2Client ec2Client;
protected final Predicate<RunningInstance> instanceStateTerminated; protected final Predicate<RunningInstance> instanceStateTerminated;
protected final GetRegionFromNodeOrDefault getRegionFromNodeOrDefault; protected final GetRegionFromLocation getRegionFromLocation;
protected final GetNodeMetadataStrategy getNodeMetadataStrategy; protected final GetNodeMetadataStrategy getNodeMetadataStrategy;
@Inject @Inject
protected EC2DestroyNodeStrategy(EC2Client ec2Client, protected EC2DestroyNodeStrategy(EC2Client ec2Client,
@Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated, @Named("TERMINATED") Predicate<RunningInstance> instanceStateTerminated,
GetRegionFromNodeOrDefault getRegionFromNodeOrDefault, GetRegionFromLocation getRegionFromLocation,
GetNodeMetadataStrategy getNodeMetadataStrategy) { GetNodeMetadataStrategy getNodeMetadataStrategy) {
this.ec2Client = ec2Client; this.ec2Client = ec2Client;
this.instanceStateTerminated = instanceStateTerminated; this.instanceStateTerminated = instanceStateTerminated;
this.getRegionFromNodeOrDefault = getRegionFromNodeOrDefault; this.getRegionFromLocation = getRegionFromLocation;
this.getNodeMetadataStrategy = getNodeMetadataStrategy; this.getNodeMetadataStrategy = getNodeMetadataStrategy;
} }
@Override @Override
public boolean execute(ComputeMetadata metadata) { public boolean execute(Location location, String id) {
NodeMetadata node = metadata instanceof NodeMetadata ? NodeMetadata.class.cast(metadata) String region = getRegionFromLocation.apply(location);
: getNodeMetadataStrategy.execute(metadata); ec2Client.getInstanceServices().terminateInstancesInRegion(region, id);
String region = getRegionFromNodeOrDefault.apply(node);
ec2Client.getInstanceServices().terminateInstancesInRegion(region, node.getId());
return instanceStateTerminated.apply(Iterables.getOnlyElement(Iterables.concat(ec2Client 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.OsFamily;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
@ -138,7 +139,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
result.getKeyMaterial())); result.getKeyMaterial()));
} finally { } finally {
client.destroyNodesWithTag(tag); client.destroyNodesMatching(NodePredicates.withTag(tag));
if (startedId != null) { if (startedId != null) {
// ensure we didn't delete these resources! // ensure we didn't delete these resources!
assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1);
@ -190,7 +191,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assert group.getIpPermissions().size() == 0 : group; assert group.getIpPermissions().size() == 0 : group;
} finally { } finally {
client.destroyNodesWithTag(tag); client.destroyNodesMatching(NodePredicates.withTag(tag));
if (startedId != null) { if (startedId != null) {
// ensure we didn't delete these resources! // ensure we didn't delete these resources!
assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1); 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 [org.jclouds.compute.domain
Template TemplateBuilder ComputeMetadata NodeMetadata Size OsFamily Template TemplateBuilder ComputeMetadata NodeMetadata Size OsFamily
Image Architecture] Image Architecture]
[org.jclouds.compute.options TemplateOptions GetNodesOptions] [org.jclouds.compute.options TemplateOptions]
[org.jclouds.compute.predicates
NodePredicates]
[com.google.common.collect ImmutableSet])) [com.google.common.collect ImmutableSet]))
(try (try
@ -121,26 +123,12 @@ See http://code.google.com/p/jclouds for details."
(defn nodes-with-tag (defn nodes-with-tag
[#^String tag #^ComputeService compute] [#^String tag #^ComputeService compute]
(seq (.listNodesWithTag compute tag))) (seq (.listNodesMatching(compute (NodePredicates/withTag tag)))))
(def #^{:private true} list-nodes-map
{ :with-details #(when %2 (.withDetails %1)) })
(defn nodes (defn nodes
"Retrieve the existing nodes for the compute context. "Retrieve the existing nodes for the compute context."
Options are: [#^ComputeService compute]
:with-details true" (seq (.listNodes compute)))
([] (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*))))
(defn images (defn images
"Retrieve the available images for the compute context." "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 (defn #^NodeMetadata node-details
"Retrieve the node metadata." "Retrieve the node metadata."
([node] (node-details node *compute*)) ([location id] (node-details location id *compute*))
([node #^ComputeService compute] ([#^Location location id #^ComputeService compute]
(.getNodeMetadata compute node ))) (.getNodeMetadata compute location id)))
(defn reboot-nodes (defn reboot-nodes-with-tag
"Reboot all the nodes with the given 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] ([#^String tag #^ComputeService compute]
(.rebootNodesWithTag compute tag ))) (.rebootNodesMatching(compute (NodePredicates/withTag tag)))))
(defn reboot-node (defn reboot-node
"Reboot a given node." "Reboot a given node."
([node] (reboot-node node *compute*)) ([location id] (reboot-node location id *compute*))
([#^ComputeMetadata node #^ComputeService compute] ([#^Location location id #^ComputeService compute]
(.rebootNode compute node ))) (.rebootNode compute location id)))
(defn destroy-nodes (defn destroy-nodes-with-tag
"Destroy all the nodes with the given 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] ([#^String tag #^ComputeService compute]
(.destroyNodesWithTag compute tag ))) (seq (.destroyNodesMatching(compute (NodePredicates/withTag tag))))))
(defn destroy-node (defn destroy-node
"Destroy a given node." "Destroy a given node."
([node] (destroy-node node *compute*)) ([location id] (destroy-node location id *compute*))
([#^ComputeMetadata node #^ComputeServiceContext compute] ([#^Location location id #^ComputeService compute]
(.destroyNode compute node))) (.destroyNode compute location id)))
(defmacro state-predicate [node state] (defmacro state-predicate [node state]
`(= (.getState ~node) `(= (.getState ~node)
@ -407,4 +395,3 @@ There are many options to use for the default template
(if next (if next
(recur next remaining))))) (recur next remaining)))))
(.build builder))) (.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.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.BaseComputeService; import org.jclouds.compute.internal.BaseComputeService;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.ExecResponse;
@ -80,12 +79,6 @@ public interface ComputeService {
*/ */
Set<? extends ComputeMetadata> listNodes(); 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, * 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 * 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 * destroy the node. If it is the only node in a tag set, the dependent resources will also be
* destroyed. * 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 * 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. * resources it uses, such as keypairs, are also destroyed.
* *
* @return list of nodes destroyed * @return list of nodes destroyed
*/ */
void destroyNodesWithTag(String tag); Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter);
/** /**
* reboot the node. * 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 * nodes matching the filter are treated as a logical set. Using this command, you can save time
* rebooting the nodes in parallel. * by rebooting the nodes in parallel.
*/ */
void rebootNodesWithTag(String tag); void rebootNodesMatching(Predicate<NodeMetadata> filter);
/** /**
* Find a node by its id * 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 * Runs the script without any additional options
* *
* @see #runScriptOnNodesMatching(Predicate, byte[], org.jclouds.compute.options.RunScriptOptions) * @see #runScriptOnNodesMatching(Predicate, byte[],
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String) * org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
*/ */
Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript) Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
throws RunScriptOnNodesException; Predicate<NodeMetadata> filter, byte[] runScript) throws RunScriptOnNodesException;
/** /**
* Run the script on all nodes with the specific tag. * Run the script on all nodes with the specific tag.
* *
* @param filter * @param filter
* Predicate-based filter to define on which nodes the script is to be * Predicate-based filter to define on which nodes the script is to be executed
* executed
* @param runScript * @param runScript
* script to run in byte format. If the script is a string, use * script to run in byte format. If the script is a string, use
* {@link String#getBytes()} to retrieve the bytes * {@link String#getBytes()} to retrieve the bytes
* @param options * @param options
* nullable options to how to run the script, whether to override credentials * nullable options to how to run the script, whether to override credentials
* @return map with node identifiers and corresponding responses * @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, Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
RunScriptOptions options) throws RunScriptOnNodesException; 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.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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.awaitCompletion;
import static org.jclouds.concurrent.ConcurrentUtils.makeListenable; import static org.jclouds.concurrent.ConcurrentUtils.makeListenable;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
@ -48,13 +46,11 @@ import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException; import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.RunScriptOnNodesException; import org.jclouds.compute.RunScriptOnNodesException;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.options.RunScriptOptions; import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.reference.ComputeServiceConstants; 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.Predicate;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -102,7 +97,6 @@ public class BaseComputeService implements ComputeService {
protected final Provider<TemplateBuilder> templateBuilderProvider; protected final Provider<TemplateBuilder> templateBuilderProvider;
protected final ComputeUtils utils; protected final ComputeUtils utils;
protected final ExecutorService executor; protected final ExecutorService executor;
protected final ComputeMetadataToNodeMetadata computeMetadataToNodeMetadata;
@Inject @Inject
protected BaseComputeService(ComputeServiceContext context, protected BaseComputeService(ComputeServiceContext context,
@ -128,7 +122,6 @@ public class BaseComputeService implements ComputeService {
"templateBuilderProvider"); "templateBuilderProvider");
this.utils = checkNotNull(utils, "utils"); this.utils = checkNotNull(utils, "utils");
this.executor = checkNotNull(executor, "executor"); this.executor = checkNotNull(executor, "executor");
this.computeMetadataToNodeMetadata = new ComputeMetadataToNodeMetadata();
} }
@Override @Override
@ -157,27 +150,24 @@ public class BaseComputeService implements ComputeService {
} }
@Override @Override
public void destroyNode(ComputeMetadata node) { public void destroyNode(Location location, String id) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkNotNull(location, "location");
+ node.getType()); checkNotNull(id, "id");
checkNotNull(node.getId(), "node.id"); logger.debug(">> destroying node(%s/%s)", location.getId(), id);
logger.debug(">> destroying node(%s)", node.getId()); boolean successful = destroyNodeStrategy.execute(location, id);
boolean successful = destroyNodeStrategy.execute(node); logger.debug("<< destroyed node(%s/%s) success(%s)", location.getId(), id, successful);
logger.debug("<< destroyed node(%s) success(%s)", node.getId(), successful);
} }
@Override @Override
public void destroyNodesWithTag(String tag) { // TODO parallel public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> destroying nodes by tag(%s)", tag); logger.debug(">> destroying nodes matching(%s)", filter);
Iterable<? extends NodeMetadata> nodesToDestroy = Iterables.filter(doListNodesWithTag(tag),
Predicates.not(NodePredicates.TERMINATED));
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap(); Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
final List<NodeMetadata> destroyedNodes = Lists.newArrayList(); final Set<NodeMetadata> destroyedNodes = Sets.newLinkedHashSet();
for (final NodeMetadata node : nodesToDestroy) { for (final NodeMetadata node : nodesMatchingFilterAndNotTerminated(filter)) {
responses.put(node, makeListenable(executor.submit(new Callable<Void>() { responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
destroyNode(node); destroyNode(node.getLocation(), node.getId());
destroyedNodes.add(node); destroyedNodes.add(node);
return null; return null;
} }
@ -185,49 +175,31 @@ public class BaseComputeService implements ComputeService {
} }
awaitCompletion(responses, executor, null, logger, "destroying nodes"); awaitCompletion(responses, executor, null, logger, "destroying nodes");
logger.debug("<< destroyed"); 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 @Override
public Set<? extends ComputeMetadata> listNodes() { public Set<? extends ComputeMetadata> listNodes() {
return listNodes(null); logger.debug(">> listing nodes");
} Set<? extends ComputeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy.list());
@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("<< list(%d)", set.size()); logger.debug("<< list(%d)", set.size());
return set; 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 @Override
public NodeMetadata apply(ComputeMetadata from) { public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
return from instanceof NodeMetadata ? NodeMetadata.class.cast(from) checkNotNull(filter, "filter");
: getNodeMetadata(from); logger.debug(">> listing node details matching(%s)", filter);
} Set<? extends NodeMetadata> set = Sets.newLinkedHashSet(listNodesStrategy
} .listDetailsOnNodesMatching(filter));
logger.debug("<< list(%d)", set.size());
@Override return set;
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;
} }
@Override @Override
@ -251,33 +223,31 @@ public class BaseComputeService implements ComputeService {
} }
@Override @Override
public NodeMetadata getNodeMetadata(ComputeMetadata node) { public NodeMetadata getNodeMetadata(Location location, String id) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkNotNull(location, "location");
+ node.getType()); checkNotNull(id, "id");
return getNodeMetadataStrategy.execute(node); return getNodeMetadataStrategy.execute(location, id);
} }
@Override @Override
public void rebootNode(ComputeMetadata node) { public void rebootNode(Location location, String id) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkNotNull(location, "location");
+ node.getType()); checkNotNull(id, "id");
checkNotNull(node.getId(), "node.id"); logger.debug(">> rebooting node(%s/%s)", location.getId(), id);
logger.debug(">> rebooting node(%s)", node.getId()); boolean successful = rebootNodeStrategy.execute(location, id);
boolean successful = rebootNodeStrategy.execute(node); logger.debug("<< rebooted node(%s/%s) success(%s)", location.getId(), id, successful);
logger.debug("<< rebooted node(%s) success(%s)", node.getId(), successful);
} }
@Override @Override
public void rebootNodesWithTag(String tag) { // TODO parallel public void rebootNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> rebooting nodes by tag(%s)", tag); logger.debug(">> rebooting nodes matching(%s)", filter);
Iterable<? extends NodeMetadata> nodesToReboot = Iterables.filter(doListNodesWithTag(tag),
Predicates.not(NodePredicates.TERMINATED));
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap(); 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>() { responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@Override @Override
public Void call() throws Exception { public Void call() throws Exception {
rebootNode(node); rebootNode(node.getLocation(), node.getId());
return null; return null;
} }
}), executor)); }), executor));
@ -290,10 +260,11 @@ public class BaseComputeService implements ComputeService {
* @throws RunScriptOnNodesException * @throws RunScriptOnNodesException
* @see #runScriptOnNodesMatching(Predicate, byte[], * @see #runScriptOnNodesMatching(Predicate, byte[],
* org.jclouds.compute.options.RunScriptOptions) * 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, @Override
byte[] runScript) throws RunScriptOnNodesException { public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(
Predicate<NodeMetadata> filter, byte[] runScript) throws RunScriptOnNodesException {
return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE); return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE);
} }
@ -311,12 +282,13 @@ public class BaseComputeService implements ComputeService {
* @throws RunScriptOnNodesException * @throws RunScriptOnNodesException
* if anything goes wrong during script execution * 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, public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
final byte[] runScript, @Nullable final RunScriptOptions options) final byte[] runScript, @Nullable final RunScriptOptions options)
throws RunScriptOnNodesException { throws RunScriptOnNodesException {
Iterable<? extends NodeMetadata> nodes = verifyParametersAndGetNodes(filter, runScript, Iterable<? extends NodeMetadata> nodes = verifyParametersAndListNodes(filter, runScript,
(options != null) ? options : RunScriptOptions.NONE); (options != null) ? options : RunScriptOptions.NONE);
final Map<NodeMetadata, ExecResponse> execs = Maps.newHashMap(); 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) { Predicate<NodeMetadata> filter, byte[] runScript, final RunScriptOptions options) {
checkNotNull(filter, "Filter must be provided"); checkNotNull(filter, "Filter must be provided");
checkNotNull(runScript, checkNotNull(runScript,
"The script (represented by bytes array - use \"script\".getBytes() must be provided"); "The script (represented by bytes array - use \"script\".getBytes() must be provided");
checkNotNull(options, "options"); 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>() { 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> * <li>run the script as root (versus running with current privileges)</li>
* </ul> * </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 Credentials overridingCredentials;
private boolean runAsRoot = true; private boolean runAsRoot = true;

View File

@ -43,6 +43,90 @@ public class TemplateOptions {
public static final TemplateOptions NONE = new 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 int[] inboundPorts = new int[] { 22 };
protected byte[] script; protected byte[] script;

View File

@ -30,6 +30,7 @@ import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Sets; 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. * 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 * tag to match the items
* @return predicate * @return predicate
*/ */
public static Predicate<NodeMetadata> activeWithTag(final String tag) { public static Predicate<NodeMetadata> runningWithTag(final String tag) {
checkNotEmpty(tag, "Tag must be defined"); checkNotEmpty(tag, "Tag must be defined");
return new Predicate<NodeMetadata>() { return new Predicate<NodeMetadata>() {
@Override @Override
@ -105,7 +113,7 @@ public class NodePredicates {
@Override @Override
public String toString() { public String toString() {
return "activeWithTag(" + tag + ")"; return "runningWithTag(" + tag + ")";
} }
}; };
} }

View File

@ -19,7 +19,7 @@
package org.jclouds.compute.strategy; 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 * 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 { public interface DestroyNodeStrategy {
boolean execute(ComputeMetadata node); boolean execute(Location location, String id);
} }

View File

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

View File

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

View File

@ -18,6 +18,7 @@
*/ */
package org.jclouds.gogrid.compute.config; 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.compute.domain.OsFamily.CENTOS;
import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAULT_DC; 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.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl; 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;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -137,9 +138,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName( Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
node.getName())); new Long(id)));
client.getServerServices().power(server.getName(), PowerCommand.RESTART); client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server); serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START); client.getServerServices().power(server.getName(), PowerCommand.START);
@ -160,11 +161,16 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
} }
@Override @Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) { public Iterable<? extends ComputeMetadata> list() {
return Iterables.transform(client.getServerServices().getServerList(), return listDetailsOnNodesMatching(NodePredicates.all());
serverToNodeMetadata);
} }
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata), filter);
}
} }
@Singleton @Singleton
@ -180,9 +186,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
} }
@Override @Override
public NodeMetadata execute(ComputeMetadata node) { public NodeMetadata execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName( Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
node.getName())); new Long(checkNotNull(id, "id"))));
return server == null ? null : serverToNodeMetadata.apply(server); return server == null ? null : serverToNodeMetadata.apply(server);
} }
} }
@ -200,9 +206,9 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName( Server server = Iterables.getOnlyElement(client.getServerServices().getServersById(
node.getName())); new Long(id)));
client.getServerServices().deleteByName(server.getName()); client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server); 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.BaseComputeService;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl; 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;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -142,8 +142,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
int serverId = Integer.parseInt(node.getId()); int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place // if false server wasn't around in the first place
client.rebootServer(serverId, RebootType.HARD); client.rebootServer(serverId, RebootType.HARD);
Server server = client.getServer(serverId); Server server = client.getServer(serverId);
@ -165,8 +165,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
int serverId = Integer.parseInt(node.getId()); int serverId = Integer.parseInt(id);
// if false server wasn't around in the first place // if false server wasn't around in the first place
if (!client.deleteServer(serverId)) if (!client.deleteServer(serverId))
return false; return false;
@ -216,11 +216,16 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
} }
@Override @Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) { public Iterable<? extends ComputeMetadata> list() {
return Iterables.transform(client.listServers(ListOptions.Builder.withDetails()), return listDetailsOnNodesMatching(NodePredicates.all());
serverToNodeMetadata);
} }
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(
Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.listServers(ListOptions.Builder
.withDetails()), serverToNodeMetadata), filter);
}
} }
@Singleton @Singleton
@ -237,8 +242,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
} }
@Override @Override
public NodeMetadata execute(ComputeMetadata node) { public NodeMetadata execute(Location location, String id) {
int serverId = Integer.parseInt(node.getId()); int serverId = Integer.parseInt(id);
Server server = client.getServer(serverId); Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server); 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.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl; 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;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -140,8 +140,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
Long serverId = Long.parseLong(node.getId()); Long serverId = Long.parseLong(id);
// if false server wasn't around in the first place // if false server wasn't around in the first place
return client.restartServer(serverId).getState() == RunningState.RUNNING; return client.restartServer(serverId).getState() == RunningState.RUNNING;
} }
@ -161,8 +161,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
long serverId = Long.parseLong(node.getId()); long serverId = Long.parseLong(id);
client.destroyServer(serverId); client.destroyServer(serverId);
return serverDestroyed.apply(client.getServer(serverId)); return serverDestroyed.apply(client.getServer(serverId));
} }
@ -220,8 +220,15 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
} }
@Override @Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) { public Iterable<? extends ComputeMetadata> list() {
return Iterables.transform(client.getServerList(), serverToNodeMetadata); 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 @Override
public NodeMetadata execute(ComputeMetadata node) { public NodeMetadata execute(Location location, String id) {
long serverId = Long.parseLong(node.getId()); // TODO location
long serverId = Long.parseLong(id);
Server server = client.getServer(serverId); Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server); 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.NodeMetadata;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import com.google.common.base.CaseFormat; import com.google.common.base.CaseFormat;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.inject.Provider; import com.google.inject.Provider;
/** /**
@ -219,19 +221,21 @@ public class ComputeTask extends Task {
private void destroy(ComputeService computeService) { private void destroy(ComputeService computeService) {
log(String.format("destroy tag: %s", nodeElement.getTag())); log(String.format("destroy tag: %s", nodeElement.getTag()));
computeService.destroyNodesWithTag(nodeElement.getTag()); computeService.destroyNodesMatching(NodePredicates.withTag(nodeElement.getTag()));
} }
private void get(ComputeService computeService) { private void get(ComputeService computeService) {
log(String.format("get tag: %s", nodeElement.getTag())); 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); logDetails(computeService, node);
} }
} }
private void logDetails(ComputeService computeService, ComputeMetadata node) { private void logDetails(ComputeService computeService, ComputeMetadata node) {
NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node)
: computeService.getNodeMetadata(node); : computeService.getNodeMetadata(node.getLocation(), node.getId());
log(String log(String
.format( .format(
" node id=%s, name=%s, tag=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, extra=%s", " 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; package org.jclouds.vcloud.compute.config;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OsFamily.UBUNTU; import static org.jclouds.compute.domain.OsFamily.UBUNTU;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount; 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.Size;
import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.domain.internal.SizeImpl; import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl; import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.compute.options.GetNodesOptions;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero; import org.jclouds.compute.predicates.ScriptStatusReturnsZero;
import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -163,8 +162,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
Task task = client.resetVApp(node.getId()); Task task = client.resetVApp(id);
return taskTester.apply(task.getId()); return taskTester.apply(task.getId());
} }
@ -180,8 +179,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@Override @Override
public boolean execute(ComputeMetadata node) { public boolean execute(Location location, String id) {
computeClient.stop(checkNotNull(node.getId(), "node.id")); computeClient.stop(checkNotNull(id, "node.id"));
return true; return true;
} }
@ -241,11 +240,31 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@Override @Override
public Iterable<? extends ComputeMetadata> execute(GetNodesOptions options) { public Iterable<ComputeMetadata> list() {
Set<ComputeMetadata> nodes = Sets.newHashSet(); Set<ComputeMetadata> nodes = Sets.newHashSet();
for (NamedResource vdc : client.getDefaultOrganization().getVDCs().values()) { for (NamedResource vdc : client.getDefaultOrganization().getVDCs().values()) {
for (NamedResource resource : client.getVDC(vdc.getId()).getResourceEntities().values()) { for (NamedResource resource : client.getVDC(vdc.getId()).getResourceEntities().values()) {
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) { 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); addVAppToSetRetryingIfNotYetPresent(nodes, vdc, resource);
} }
} }
@ -254,7 +273,7 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@VisibleForTesting @VisibleForTesting
void addVAppToSetRetryingIfNotYetPresent(Set<ComputeMetadata> nodes, NamedResource vdc, void addVAppToSetRetryingIfNotYetPresent(Set<NodeMetadata> nodes, NamedResource vdc,
NamedResource resource) { NamedResource resource) {
NodeMetadata node = null; NodeMetadata node = null;
int i = 0; int i = 0;
@ -284,11 +303,9 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@Override @Override
public NodeMetadata execute(ComputeMetadata node) { public NodeMetadata execute(Location location, String id) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " return getNodeMetadataByIdInVDC(checkNotNull(location, "location").getId(), checkNotNull(
+ node.getType()); id, "node.id"));
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location").getId(),
checkNotNull(node.getId(), "node.id"));
} }
} }

View File

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

View File

@ -48,7 +48,7 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assert node.getId() != null; assert node.getId() != null;
assert node.getLocation() != null; assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE); 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("processor/count") != null;
assert allData.getExtra().get("disk_drive/1/kb") != null; assert allData.getExtra().get("disk_drive/1/kb") != null;
assert allData.getExtra().get("memory/mb") != 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.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope; import org.jclouds.domain.LocationScope;
@ -124,7 +124,7 @@ public class VCloudComputeServiceContextModuleTest {
VCloudListNodesStrategy strategy = new VCloudListNodesStrategy(client, computeClient, VCloudListNodesStrategy strategy = new VCloudListNodesStrategy(client, computeClient,
vAppStatusToNodeState, getExtra, findLocationForResourceInVDC, images); vAppStatusToNodeState, getExtra, findLocationForResourceInVDC, images);
Set<ComputeMetadata> nodes = Sets.newHashSet(); Set<NodeMetadata> nodes = Sets.newHashSet();
NamedResource vdc = new NamedResourceImpl("1", null, null, null); NamedResource vdc = new NamedResourceImpl("1", null, null, null);
NamedResource resource = new NamedResourceImpl("10", null, null, null); NamedResource resource = new NamedResourceImpl("10", null, null, null);