JCLOUDS-610: Return the affected nodes from resumeNodesMatching, suspendNodesMatching and rebootNodesMatching

Methods have been refactored to match the functionality provided by destroyNodesMatching.
This commit is contained in:
Christopher Dancy 2014-06-22 11:18:42 -04:00 committed by Andrew Phillips
parent 3fc2f85254
commit 7f2845349c
3 changed files with 91 additions and 38 deletions

View File

@ -193,12 +193,14 @@ public interface ComputeService {
* *
* affected nodes may not resume with the same IP address(es) * affected nodes may not resume with the same IP address(es)
* *
* @return list of nodes resumed
*
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* if the underlying provider doesn't support suspend/resume * if the underlying provider doesn't support suspend/resume
* @throws NoSuchElementException * @throws NoSuchElementException
* if no nodes matched the predicate specified * if no nodes matched the predicate specified
*/ */
void resumeNodesMatching(Predicate<NodeMetadata> filter); Set<? extends NodeMetadata> resumeNodesMatching(Predicate<NodeMetadata> filter);
/** /**
* suspend the node, given its id. This will result in * suspend the node, given its id. This will result in
@ -221,12 +223,14 @@ public interface ComputeService {
* *
* affected nodes may not resume with the same IP address(es) * affected nodes may not resume with the same IP address(es)
* *
* @return list of nodes suspended
*
* @throws UnsupportedOperationException * @throws UnsupportedOperationException
* if the underlying provider doesn't support suspend/resume * if the underlying provider doesn't support suspend/resume
* @throws NoSuchElementException * @throws NoSuchElementException
* if no nodes matched the predicate specified * if no nodes matched the predicate specified
*/ */
void suspendNodesMatching(Predicate<NodeMetadata> filter); Set<? extends NodeMetadata> suspendNodesMatching(Predicate<NodeMetadata> filter);
/** /**
* destroy the node, given its id. If it is the only node in a tag set, the dependent resources * destroy the node, given its id. If it is the only node in a tag set, the dependent resources
@ -252,10 +256,12 @@ public interface ComputeService {
* nodes matching the filter are treated as a logical set. Using this command, you can save time * nodes matching the filter are treated as a logical set. Using this command, you can save time
* by rebooting the nodes in parallel. * by rebooting the nodes in parallel.
* *
* @return list of nodes rebooted
*
* @throws NoSuchElementException * @throws NoSuchElementException
* if no nodes matched the predicate specified * if no nodes matched the predicate specified
*/ */
void rebootNodesMatching(Predicate<NodeMetadata> filter); Set<? extends NodeMetadata> rebootNodesMatching(Predicate<NodeMetadata> filter);
/** /**
* Find a node by its id. * Find a node by its id.

View File

@ -23,7 +23,6 @@ import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.newLinkedHashMap;
import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.collect.Sets.newLinkedHashSet;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
@ -256,7 +255,7 @@ public class BaseComputeService implements ComputeService {
@Override @Override
public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) { public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> destroying nodes matching(%s)", filter); logger.debug(">> destroying nodes matching(%s)", filter);
Set<NodeMetadata> set = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter), Set<NodeMetadata> destroyNodes = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
new Function<NodeMetadata, ListenableFuture<? extends NodeMetadata>>() { new Function<NodeMetadata, ListenableFuture<? extends NodeMetadata>>() {
// TODO make an async interface instead of re-wrapping // TODO make an async interface instead of re-wrapping
@ -274,10 +273,10 @@ public class BaseComputeService implements ComputeService {
} }
}, userExecutor, null, logger, "destroyNodesMatching(" + filter + ")")); }, userExecutor, null, logger, "destroyNodesMatching(" + filter + ")"));
logger.debug("<< destroyed(%d)", set.size()); logger.debug("<< destroyed(%d)", destroyNodes.size());
cleanUpIncidentalResourcesOfDeadNodes(set); cleanUpIncidentalResourcesOfDeadNodes(destroyNodes);
return set; return destroyNodes;
} }
/** /**
@ -432,19 +431,29 @@ public class BaseComputeService implements ComputeService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void rebootNodesMatching(Predicate<NodeMetadata> filter) { public Set<? extends NodeMetadata> rebootNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> rebooting nodes matching(%s)", filter); logger.debug(">> rebooting nodes matching(%s)", filter);
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), Set<NodeMetadata> rebootNodes = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
new Function<NodeMetadata, ListenableFuture<? extends Void>>() { new Function<NodeMetadata, ListenableFuture<? extends NodeMetadata>>() {
// TODO use native async
// TODO make an async interface instead of re-wrapping
@Override @Override
public ListenableFuture<Void> apply(NodeMetadata from) { public ListenableFuture<NodeMetadata> apply(final NodeMetadata from) {
rebootNode(from.getId()); return userExecutor.submit(new Callable<NodeMetadata>() {
return immediateFuture(null); public NodeMetadata call() throws Exception {
rebootNode(from.getId());
return from;
}
public String toString() {
return "rebootNode(" + from.getId() + ")";
}
});
} }
}, userExecutor, null, logger, "rebootNodesMatching(" + filter + ")"); }, userExecutor, null, logger, "rebootNodesMatching(" + filter + ")"));
logger.debug("<< rebooted"); logger.debug("<< rebooted(%d)", rebootNodes.size());
return rebootNodes;
} }
/** /**
@ -463,19 +472,29 @@ public class BaseComputeService implements ComputeService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void resumeNodesMatching(Predicate<NodeMetadata> filter) { public Set<? extends NodeMetadata> resumeNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> resuming nodes matching(%s)", filter); logger.debug(">> resuming nodes matching(%s)", filter);
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), Set<NodeMetadata> resumeNodes = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
new Function<NodeMetadata, ListenableFuture<? extends Void>>() { new Function<NodeMetadata, ListenableFuture<? extends NodeMetadata>>() {
// TODO use native async
// TODO make an async interface instead of re-wrapping
@Override @Override
public ListenableFuture<Void> apply(NodeMetadata from) { public ListenableFuture<NodeMetadata> apply(final NodeMetadata from) {
resumeNode(from.getId()); return userExecutor.submit(new Callable<NodeMetadata>() {
return immediateFuture(null); public NodeMetadata call() throws Exception {
resumeNode(from.getId());
return from;
}
public String toString() {
return "resumeNode(" + from.getId() + ")";
}
});
} }
}, userExecutor, null, logger, "resumeNodesMatching(" + filter + ")"); }, userExecutor, null, logger, "resumeNodesMatching(" + filter + ")"));
logger.debug("<< resumed"); logger.debug("<< resumed(%d)", resumeNodes.size());
return resumeNodes;
} }
/** /**
@ -494,19 +513,29 @@ public class BaseComputeService implements ComputeService {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public void suspendNodesMatching(Predicate<NodeMetadata> filter) { public Set<? extends NodeMetadata> suspendNodesMatching(Predicate<NodeMetadata> filter) {
logger.debug(">> suspending nodes matching(%s)", filter); logger.debug(">> suspending nodes matching(%s)", filter);
transformParallel(nodesMatchingFilterAndNotTerminatedExceptionIfNotFound(filter), Set<NodeMetadata> suspendNodes = ImmutableSet.copyOf(transformParallel(nodesMatchingFilterAndNotTerminated(filter),
new Function<NodeMetadata, ListenableFuture<? extends Void>>() { new Function<NodeMetadata, ListenableFuture<? extends NodeMetadata>>() {
// TODO use native async
// TODO make an async interface instead of re-wrapping
@Override @Override
public ListenableFuture<Void> apply(NodeMetadata from) { public ListenableFuture<NodeMetadata> apply(final NodeMetadata from) {
suspendNode(from.getId()); return userExecutor.submit(new Callable<NodeMetadata>() {
return immediateFuture(null); public NodeMetadata call() throws Exception {
suspendNode(from.getId());
return from;
}
public String toString() {
return "suspendNode(" + from.getId() + ")";
}
});
} }
}, userExecutor, null, logger, "suspendNodesMatching(" + filter + ")"); }, userExecutor, null, logger, "suspendNodesMatching(" + filter + ")"));
logger.debug("<< suspended"); logger.debug("<< suspended(%d)", suspendNodes.size());
return suspendNodes;
} }
/** /**

View File

@ -553,14 +553,26 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte
@Test(enabled = true, dependsOnMethods = "testGet") @Test(enabled = true, dependsOnMethods = "testGet")
public void testReboot() throws Exception { public void testReboot() throws Exception {
client.rebootNodesMatching(inGroup(group));// TODO test Set<? extends NodeMetadata> rebootNodes = client.rebootNodesMatching(inGroup(group));
for (ComputeMetadata node : rebootNodes) {
assertNotNull(node);
assert node.getProviderId() != null : node;
assert node.getLocation() != null : node;
}
// validation // validation
testGet(); testGet();
} }
@Test(enabled = true, dependsOnMethods = "testReboot") @Test(enabled = true, dependsOnMethods = "testReboot")
public void testSuspendResume() throws Exception { public void testSuspendResume() throws Exception {
client.suspendNodesMatching(inGroup(group));
Set<? extends NodeMetadata> suspendedNodes = client.suspendNodesMatching(inGroup(group));
for (ComputeMetadata node : suspendedNodes) {
assertNotNull(node);
assert node.getProviderId() != null : node;
assert node.getLocation() != null : node;
}
Set<? extends NodeMetadata> stoppedNodes = refreshNodes(); Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
@ -576,7 +588,13 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte
}) : stoppedNodes; }) : stoppedNodes;
client.resumeNodesMatching(inGroup(group)); Set<? extends NodeMetadata> resumedNodes = client.resumeNodesMatching(inGroup(group));
for (ComputeMetadata node : resumedNodes) {
assertNotNull(node);
assert node.getProviderId() != null : node;
assert node.getLocation() != null : node;
}
testGet(); testGet();
} }