diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index 22e1dca93a..b1c94e8791 100644
--- a/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -42,12 +42,13 @@ import org.jclouds.Constants;
import org.jclouds.compute.config.CustomizationResponse;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
+import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
import org.jclouds.compute.strategy.ListNodesStrategy;
-import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
@@ -61,12 +62,12 @@ import com.google.common.collect.Multimap;
@Singleton
public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNodesInGroupThenAddToSet {
- private class AddNode implements Callable> {
+ protected class AddNode implements Callable> {
private final String name;
private final String group;
private final Template template;
- private AddNode(String name, String group, Template template) {
+ public AddNode(String name, String group, Template template) {
this.name = checkNotNull(name, "name");
this.group = checkNotNull(group, "group");
this.template = checkNotNull(template, "template");
@@ -75,9 +76,8 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo
@Override
public AtomicReference call() throws Exception {
NodeMetadata node = null;
- logger.debug(">> adding node location(%s) name(%s) image(%s) hardware(%s)",
- template.getLocation().getId(), name, template.getImage().getProviderId(), template.getHardware()
- .getProviderId());
+ logger.debug(">> adding node location(%s) name(%s) image(%s) hardware(%s)", template.getLocation().getId(),
+ name, template.getImage().getProviderId(), template.getHardware().getProviderId());
node = addNodeWithGroupStrategy.createNodeWithGroupEncodedIntoName(group, name, template);
logger.debug("<< %s node(%s)", node.getState(), node.getId());
return new AtomicReference(node);
@@ -121,13 +121,54 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo
Map badNodes, Multimap customizationResponses) {
Map> responses = newLinkedHashMap();
for (String name : getNextNames(group, template, count)) {
- responses.put(name, compose(executor.submit(new AddNode(name, group, template)),
- customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(template.getOptions(),
- goodNodes, badNodes, customizationResponses), executor));
+ responses.put(name, compose(createNodeInGroupWithNameAndTemplate(group, name, template),
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory.create(template.getOptions(), goodNodes,
+ badNodes, customizationResponses), executor));
}
return responses;
}
+ /**
+ * This calls logic necessary to create a node and convert it from its provider-specific object
+ * to the jclouds {@link NodeMetadata} object. This call directly precedes customization, such as
+ * executing scripts.
+ *
+ *
The outcome of this operation does not imply the node is {@link NodeState#RUNNING
+ * running}. If you want to insert logic after the node is created, yet before an attempt to
+ * customize the node, then append your behaviour to this method.
+ *
+ * ex. to attach an ip address post-creation
+ *
+ *
+ * @Override
+ * protected Future<AtomicReference<NodeMetadata>> createNodeInGroupWithNameAndTemplate(String group, String name,
+ * Template template) {
+ *
+ * Future<AtomicReference<NodeMetadata>> future = super.addNodeIntoGroupWithNameAndTemplate(group, name, template);
+ * return Futures.compose(future, new Function<AtomicReference<NodeMetadata>, AtomicReference<NodeMetadata>>() {
+ *
+ * @Override
+ * public AtomicReference<NodeMetadata> apply(AtomicReference<NodeMetadata> input) {
+ * NodeMetadata node = input.get();
+ * // allocate and attach an ip
+ * input.set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.getIp())).build());
+ * return input;
+ * }
+ *
+ * }, executor);
+ * }
+ *
+ *
+ * @param group group the node belongs to
+ * @param name generated name of the node
+ * @param template user-specified template
+ * @return node that is created, yet not necessarily in {@link NodeState#RUNNING}
+ */
+ protected Future> createNodeInGroupWithNameAndTemplate(String group, String name,
+ Template template) {
+ return executor.submit(new AddNode(name, group, template));
+ }
+
/**
* Find the next node names that can be used. These will be derived from the group and the
* template. We will pre-allocate a specified quantity, and attempt to verify that there is no