added NodePredicates to simplify node filtering logic

This commit is contained in:
Alex Yarmula 2010-05-07 12:33:49 -07:00
parent dd4087982b
commit 7ccc18c0f8
4 changed files with 113 additions and 43 deletions

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.compute;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -142,6 +143,8 @@ public interface ComputeService {
* nodes which are tagged 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);
@ -172,6 +175,7 @@ public interface ComputeService {
* Runs the script without any additional options
*
* @see #runScriptOnNodesMatching(Predicate, byte[], org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
*/
Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript)
throws RunScriptOnNodesException;
@ -189,6 +193,8 @@ public interface ComputeService {
* 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
*
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
*/
Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript,
RunScriptOptions options) throws RunScriptOnNodesException;

View File

@ -28,6 +28,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
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;
@ -40,6 +41,8 @@ import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import org.jclouds.Constants;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
@ -55,6 +58,7 @@ 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;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
@ -74,6 +78,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListenableFuture;
import static org.jclouds.compute.predicates.NodePredicates.withTag;
/**
*
@ -100,20 +105,6 @@ public class BaseComputeService implements ComputeService {
protected final ExecutorService executor;
protected final ComputeMetadataToNodeMetadata computeMetadataToNodeMetadata;
private static class NodeMatchesTag implements Predicate<NodeMetadata> {
private final String tag;
public NodeMatchesTag(String tag) {
this.tag = tag;
}
@Override
public boolean apply(NodeMetadata from) {
return from.getTag().equals(tag);
}
};
@Inject
protected BaseComputeService(ComputeServiceContext context,
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
@ -180,19 +171,15 @@ public class BaseComputeService implements ComputeService {
public void destroyNodesWithTag(String tag) { // TODO parallel
logger.debug(">> destroying nodes by tag(%s)", tag);
Iterable<? extends NodeMetadata> nodesToDestroy = Iterables.filter(doListNodesWithTag(tag),
new Predicate<NodeMetadata>() {
@Override
public boolean apply(NodeMetadata input) {
return input.getState() != NodeState.TERMINATED;
}
});
Predicates.not(NodePredicates.TERMINATED));
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
final List<NodeMetadata> destroyedNodes = Lists.newArrayList();
for (final NodeMetadata node : nodesToDestroy) {
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
destroyNode(node);
destroyedNodes.add(node);
return null;
}
}), executor));
@ -224,7 +211,7 @@ public class BaseComputeService implements ComputeService {
*/
protected Set<? extends NodeMetadata> doListNodesWithTag(final String tag) {
return Sets.newHashSet(Iterables.filter(Iterables.transform(listNodesStrategy
.execute(GetNodesOptions.NONE), computeMetadataToNodeMetadata), new NodeMatchesTag(tag)));
.execute(GetNodesOptions.NONE), computeMetadataToNodeMetadata), withTag(tag)));
}
class ComputeMetadataToNodeMetadata
@ -287,13 +274,7 @@ public class BaseComputeService implements ComputeService {
public void rebootNodesWithTag(String tag) { // TODO parallel
logger.debug(">> rebooting nodes by tag(%s)", tag);
Iterable<? extends NodeMetadata> nodesToReboot = Iterables.filter(doListNodesWithTag(tag),
new Predicate<NodeMetadata>() {
@Override
public boolean apply(NodeMetadata input) {
return input.getState() != NodeState.TERMINATED;
}
});
Predicates.not(NodePredicates.TERMINATED));
Map<NodeMetadata, ListenableFuture<Void>> responses = Maps.newHashMap();
for (final NodeMetadata node : nodesToReboot) {
responses.put(node, makeListenable(executor.submit(new Callable<Void>() {
@ -311,6 +292,7 @@ public class BaseComputeService implements ComputeService {
/**
* @throws RunScriptOnNodesException
* @see #runScriptOnNodesMatching(Predicate, byte[], org.jclouds.compute.options.RunScriptOptions)
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
*/
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, byte[] runScript)
throws RunScriptOnNodesException {
@ -330,6 +312,8 @@ public class BaseComputeService implements ComputeService {
* 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
*
* @see org.jclouds.compute.predicates.NodePredicates#activeWithTag(String)
*/
public Map<NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
final byte[] runScript, @Nullable final RunScriptOptions options)

View File

@ -0,0 +1,90 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.predicates;
import com.google.common.base.Predicate;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import javax.annotation.Nullable;
import static org.jclouds.util.Utils.checkNotEmpty;
/**
* Container for node filters (predicates).
*
* This class has static methods that create customized predicates to use with
* {@link org.jclouds.compute.ComputeService}.
*
* @author Oleksiy Yarmula
*/
public class NodePredicates {
/**
* Return nodes with specified tag.
* Note: returns all nodes, regardless of the state.
*
* @param tag tag to match the items
* @return predicate
*/
public static Predicate<NodeMetadata> withTag(final String tag) {
checkNotEmpty(tag, "Tag must be defined");
return new Predicate<NodeMetadata>() {
@Override
public boolean apply(@Nullable NodeMetadata nodeMetadata) {
return tag.equals(nodeMetadata.getTag());
}
};
}
/**
* Return nodes with specified tag that are in the RUNNING state.
* @param tag tag to match the items
* @return predicate
*/
public static Predicate<NodeMetadata> activeWithTag(final String tag) {
checkNotEmpty(tag, "Tag must be defined");
return new Predicate<NodeMetadata>() {
@Override
public boolean apply(@Nullable NodeMetadata nodeMetadata) {
return tag.equals(nodeMetadata.getTag()) && nodeMetadata.getState() == NodeState.RUNNING;
}
};
}
/**
* Match nodes with State == RUNNING
*/
public static final Predicate<NodeMetadata> ACTIVE = new Predicate<NodeMetadata>() {
@Override
public boolean apply(@Nullable NodeMetadata nodeMetadata) {
return nodeMetadata.getState() == NodeState.RUNNING;
}
};
/**
* Match nodes with State == TERMINATED
*/
public static final Predicate<NodeMetadata> TERMINATED = new Predicate<NodeMetadata>() {
@Override
public boolean apply(@Nullable NodeMetadata nodeMetadata) {
return nodeMetadata.getState() == NodeState.TERMINATED;
}
};
}

View File

@ -47,6 +47,7 @@ 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;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
@ -249,15 +250,9 @@ public abstract class BaseComputeServiceLiveTest {
private Map<NodeMetadata, ExecResponse> runScriptWithCreds(String tag, OsFamily osFamily,
Credentials creds) throws RunScriptOnNodesException {
Predicate<NodeMetadata> filter = new Predicate<NodeMetadata>() {
@Override
public boolean apply(@Nullable NodeMetadata nodeMetadata) {
return true; /*accept all*/
}
};
try {
return client.runScriptOnNodesMatching(filter, buildScript(osFamily).getBytes(),
return client.runScriptOnNodesMatching(Predicates.<NodeMetadata>alwaysTrue(),
buildScript(osFamily).getBytes(),
RunScriptOptions.Builder.overrideCredentialsWith(creds));
} catch (SshException e) {
if (Throwables.getRootCause(e).getMessage().contains("Auth fail")) {
@ -323,12 +318,7 @@ 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(new Predicate<NodeMetadata>() {
@Override
public boolean apply(NodeMetadata input) {
return input.getState() == NodeState.TERMINATED;
}
})));
.listNodesWithTag(tag), Predicates.not(NodePredicates.TERMINATED)));
for (NodeMetadata node : nodes) {
metadataSet.remove(node);
NodeMetadata metadata = client.getNodeMetadata(node);