You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2015/07/30 22:00:24 UTC
[07/11] incubator-brooklyn git commit: MachineLifecycleEffectorTasks
can suspend as well as stop machines.
MachineLifecycleEffectorTasks can suspend as well as stop machines.
Leaves it to subclasses to attach the effector to entities.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f012c9c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f012c9c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f012c9c7
Branch: refs/heads/master
Commit: f012c9c7e879248b08bee6912d2698ff97e2ed9d
Parents: 415d083
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Jul 21 16:56:13 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Wed Jul 29 17:00:19 2015 +0100
----------------------------------------------------------------------
.../software/MachineLifecycleEffectorTasks.java | 127 ++++++++++++++++---
1 file changed, 108 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f012c9c7/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index ec3ae1c..920e5b9 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -63,6 +63,7 @@ import brooklyn.entity.trait.StartableMethods;
import brooklyn.event.feed.ConfigToAttributes;
import brooklyn.location.Location;
import brooklyn.location.MachineLocation;
+import brooklyn.location.MachineManagementMixins.SuspendsMachines;
import brooklyn.location.MachineProvisioningLocation;
import brooklyn.location.NoMachinesAvailableException;
import brooklyn.location.basic.AbstractLocation;
@@ -72,7 +73,6 @@ import brooklyn.location.basic.Machines;
import brooklyn.location.basic.SshMachineLocation;
import brooklyn.location.cloud.CloudLocationConfig;
import brooklyn.management.Task;
-import brooklyn.management.TaskFactory;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.config.ConfigBag;
import brooklyn.util.exceptions.Exceptions;
@@ -155,8 +155,18 @@ public abstract class MachineLifecycleEffectorTasks {
.build();
}
+ /** @see {@link #newStartEffector()} */
+ public Effector<Void> newSuspendEffector() {
+ return Effectors.effector(Void.class, "suspend")
+ .description("Suspend the process/service represented by an entity")
+ .parameter(StopSoftwareParameters.STOP_PROCESS_MODE)
+ .parameter(StopSoftwareParameters.STOP_MACHINE_MODE)
+ .impl(newSuspendEffectorTask())
+ .build();
+ }
+
/**
- * Returns the {@link TaskFactory} which supplies the implementation for the start effector.
+ * Returns the {@link EffectorBody} which supplies the implementation for the start effector.
* <p>
* Calls {@link #start(Collection)} in this class.
*/
@@ -196,7 +206,7 @@ public abstract class MachineLifecycleEffectorTasks {
}
/**
- * Calls {@link #stop()}.
+ * Calls {@link #stop(ConfigBag)}.
*
* @see {@link #newStartEffectorTask()}
*/
@@ -210,6 +220,21 @@ public abstract class MachineLifecycleEffectorTasks {
};
}
+ /**
+ * Calls {@link #suspend(ConfigBag)}.
+ *
+ * @see {@link #newStartEffectorTask()}
+ */
+ public EffectorBody<Void> newSuspendEffectorTask() {
+ return new EffectorBody<Void>() {
+ @Override
+ public Void call(ConfigBag parameters) {
+ suspend(parameters);
+ return null;
+ }
+ };
+ }
+
protected EntityInternal entity() {
return (EntityInternal) BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
}
@@ -576,6 +601,27 @@ public abstract class MachineLifecycleEffectorTasks {
* If no errors were encountered call {@link #postStopCustom()} at the end.
*/
public void stop(ConfigBag parameters) {
+ doStop(parameters, new Callable<StopMachineDetails<Integer>>() {
+ public StopMachineDetails<Integer> call() {
+ return stopAnyProvisionedMachines();
+ }
+ });
+ }
+
+ /**
+ * As {@link #stop} but calling {@link #suspendAnyProvisionedMachines} rather than
+ * {@link #stopAnyProvisionedMachines}.
+ */
+ public void suspend(ConfigBag parameters) {
+ doStop(parameters, new Callable<StopMachineDetails<Integer>>() {
+ @Override
+ public StopMachineDetails<Integer> call() throws Exception {
+ return suspendAnyProvisionedMachines();
+ }
+ });
+ }
+
+ protected void doStop(ConfigBag parameters, Callable<StopMachineDetails<Integer>> stopTask) {
preStopConfirmCustom();
log.info("Stopping {} in {}", entity(), entity().getLocations());
@@ -608,11 +654,7 @@ public abstract class MachineLifecycleEffectorTasks {
Task<StopMachineDetails<Integer>> stoppingMachine = null;
if (canStop(stopMachineMode, machine.isAbsent())) {
// Release this machine (even if error trying to stop process - we rethrow that after)
- stoppingMachine = DynamicTasks.queue("stopping (machine)", new Callable<StopMachineDetails<Integer>>() {
- public StopMachineDetails<Integer> call() {
- return stopAnyProvisionedMachines();
- }
- });
+ stoppingMachine = DynamicTasks.queue("stopping (machine)", stopTask);
DynamicTasks.drain(entity().getConfig(STOP_PROCESS_TIMEOUT), false);
@@ -750,7 +792,7 @@ public abstract class MachineLifecycleEffectorTasks {
protected abstract String stopProcessesAtMachine();
/**
- * Stop the {@link MachineLocation} the entity is provisioned at.
+ * Stop and release the {@link MachineLocation} the entity is provisioned at.
* <p>
* Can run synchronously or not, caller will submit/queue as needed, and will block on any submitted tasks.
*/
@@ -775,16 +817,63 @@ public abstract class MachineLifecycleEffectorTasks {
return new StopMachineDetails<Integer>("No machine decommissioning necessary - not a machine ("+machine+")", 0);
}
- try {
- entity().removeLocations(ImmutableList.of(machine));
- entity().setAttribute(Attributes.HOSTNAME, null);
- entity().setAttribute(Attributes.ADDRESS, null);
- entity().setAttribute(Attributes.SUBNET_HOSTNAME, null);
- entity().setAttribute(Attributes.SUBNET_ADDRESS, null);
- if (provisioner != null) provisioner.release((MachineLocation)machine);
- } catch (Throwable t) {
- throw Exceptions.propagate(t);
- }
+ clearEntityLocationAttributes(machine);
+ provisioner.release((MachineLocation)machine);
+
return new StopMachineDetails<Integer>("Decommissioned "+machine, 1);
}
+
+ /**
+ * Suspend the {@link MachineLocation} the entity is provisioned at.
+ * <p>
+ * Expects the entity's {@link SoftwareProcess#PROVISIONING_LOCATION provisioner} to be capable of
+ * {@link SuspendsMachines suspending machines}.
+ *
+ * @throws java.lang.UnsupportedOperationException if the entity's provisioner cannot suspend machines.
+ * @see brooklyn.location.MachineManagementMixins.SuspendsMachines
+ */
+ protected StopMachineDetails<Integer> suspendAnyProvisionedMachines() {
+ @SuppressWarnings("unchecked")
+ MachineProvisioningLocation<MachineLocation> provisioner = entity().getAttribute(SoftwareProcess.PROVISIONING_LOCATION);
+
+ if (Iterables.isEmpty(entity().getLocations())) {
+ log.debug("No machine decommissioning necessary for " + entity() + " - no locations");
+ return new StopMachineDetails<>("No machine suspend necessary - no locations", 0);
+ }
+
+ // Only release this machine if we ourselves provisioned it (e.g. it might be running other services)
+ if (provisioner == null) {
+ log.debug("No machine decommissioning necessary for " + entity() + " - did not provision");
+ return new StopMachineDetails<>("No machine suspend necessary - did not provision", 0);
+ }
+
+ Location machine = getLocation(null);
+ if (!(machine instanceof MachineLocation)) {
+ log.debug("No decommissioning necessary for " + entity() + " - not a machine location (" + machine + ")");
+ return new StopMachineDetails<>("No machine suspend necessary - not a machine (" + machine + ")", 0);
+ }
+
+ if (!(provisioner instanceof SuspendsMachines)) {
+ log.debug("Location provisioner ({}) cannot suspend machines", provisioner);
+ throw new UnsupportedOperationException("Location provisioner cannot suspend machines: " + provisioner);
+ }
+
+ clearEntityLocationAttributes(machine);
+ SuspendsMachines.class.cast(provisioner).suspendMachine(MachineLocation.class.cast(machine));
+
+ return new StopMachineDetails<>("Suspended " + machine, 1);
+ }
+
+ /**
+ * Nulls the attached entity's hostname, address, subnet hostname and subnet address sensors
+ * and removes the given machine from its locations.
+ */
+ protected void clearEntityLocationAttributes(Location machine) {
+ entity().removeLocations(ImmutableList.of(machine));
+ entity().setAttribute(Attributes.HOSTNAME, null);
+ entity().setAttribute(Attributes.ADDRESS, null);
+ entity().setAttribute(Attributes.SUBNET_HOSTNAME, null);
+ entity().setAttribute(Attributes.SUBNET_ADDRESS, null);
+ }
+
}