You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sv...@apache.org on 2016/10/31 11:12:53 UTC
[3/6] brooklyn-server git commit: Handle pre/post/launch errors in
AbstractSoftwareProcessDriver restart
Handle pre/post/launch errors in AbstractSoftwareProcessDriver restart
Previously if any phase errored (e.g. a post-launch comment exited with a
non-zero code) the entity would be stuck in the 'starting' state.
Fixes https://issues.apache.org/jira/browse/BROOKLYN-371
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/a974d3d9
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/a974d3d9
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/a974d3d9
Branch: refs/heads/master
Commit: a974d3d9e5e8207b64000187eaf88daccd8ef91a
Parents: dacf18b
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Mon Oct 24 11:43:15 2016 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Fri Oct 28 14:35:12 2016 +0100
----------------------------------------------------------------------
.../base/AbstractSoftwareProcessDriver.java | 48 ++++++----
.../SoftwareProcessRestartIntegrationTest.java | 99 ++++++++++++++++++++
2 files changed, 128 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a974d3d9/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
index aaa7cde..f04206f 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
@@ -305,25 +305,35 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr
}
});
- if (doFullStartOnRestart()) {
- DynamicTasks.waitForLast();
- ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STARTING);
- start();
- } else {
- DynamicTasks.queue("pre-launch-command", new Runnable() { public void run() {
- ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STARTING);
- runPreLaunchCommand();
- }});
- DynamicTasks.queue("launch (main)", new Runnable() { public void run() {
- launch();
- }});
- DynamicTasks.queue("post-launch-command", new Runnable() { public void run() {
- runPostLaunchCommand();
- }});
- DynamicTasks.queue("post-launch", new Runnable() { public void run() {
- postLaunch();
- }});
- }
+ DynamicTasks.queue("restart", new Runnable() {
+ public void run() {
+ try {
+ if (doFullStartOnRestart()) {
+ DynamicTasks.waitForLast();
+ ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STARTING);
+ start();
+ } else {
+ DynamicTasks.queue("pre-launch-command", new Runnable() { public void run() {
+ ServiceStateLogic.setExpectedState(getEntity(), Lifecycle.STARTING);
+ runPreLaunchCommand();
+ }});
+ DynamicTasks.queue("launch (main)", new Runnable() { public void run() {
+ launch();
+ }});
+ DynamicTasks.queue("post-launch-command", new Runnable() { public void run() {
+ runPostLaunchCommand();
+ }});
+ DynamicTasks.queue("post-launch", new Runnable() { public void run() {
+ postLaunch();
+ }});
+ }
+ DynamicTasks.waitForLast();
+ } catch (Exception e) {
+ ServiceStateLogic.setExpectedState(entity, Lifecycle.ON_FIRE);
+ throw Exceptions.propagate(e);
+ }
+ }
+ });
}
@Beta
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/a974d3d9/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRestartIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRestartIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRestartIntegrationTest.java
new file mode 100644
index 0000000..71d6b38
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRestartIntegrationTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.brooklyn.entity.software.base;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.test.Asserts;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+public class SoftwareProcessRestartIntegrationTest extends BrooklynAppUnitTestSupport {
+
+ @DataProvider(name = "errorPhase")
+ public Object[][] errorPhases() {
+ return new Object[][]{
+ {SoftwareProcess.PRE_LAUNCH_COMMAND},
+ {VanillaSoftwareProcess.LAUNCH_COMMAND},
+ {SoftwareProcess.POST_LAUNCH_COMMAND},
+ };
+ }
+
+ @Test(dataProvider = "errorPhase", groups = "Integration")
+ public void testEntityOnFireAfterRestartingWhenLaunchCommandFails(ConfigKey<String> key) {
+ VanillaSoftwareProcess entity = app.createAndManageChild(EntitySpec.create(VanillaSoftwareProcess.class)
+ .configure(VanillaSoftwareProcess.LAUNCH_COMMAND, "true")
+ .configure(VanillaSoftwareProcess.CHECK_RUNNING_COMMAND, "true")
+ .configure(key, "exit 1"));
+ try {
+ app.start(ImmutableList.of(app.newLocalhostProvisioningLocation()));
+ Asserts.shouldHaveFailedPreviously("entity has launch command that does not complete successfully");
+ } catch (Exception e) {
+ // expected
+ }
+
+ LastTwoServiceStatesListener listener = new LastTwoServiceStatesListener();
+ entity.subscriptions().subscribe(entity, Attributes.SERVICE_STATE_ACTUAL, listener);
+
+ EntityAsserts.assertAttributeEquals(entity, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);
+ entity.invoke(Startable.RESTART, ImmutableMap.<String, Object>of(
+ SoftwareProcess.RestartSoftwareParameters.RESTART_CHILDREN.getName(), false,
+ SoftwareProcess.RestartSoftwareParameters.RESTART_MACHINE.getName(), false));
+
+ List<Lifecycle> expected = ImmutableList.of(Lifecycle.STARTING, Lifecycle.ON_FIRE);
+ Asserts.eventually(listener, Predicates.equalTo(expected));
+ }
+
+ public static class LastTwoServiceStatesListener implements SensorEventListener<Lifecycle>, Supplier<List<Lifecycle>> {
+ final Lifecycle[] events = new Lifecycle[2];
+
+ @Override
+ public void onEvent(SensorEvent<Lifecycle> event) {
+ synchronized (events) {
+ events[0] = events[1];
+ events[1] = event.getValue();
+ }
+ }
+
+ @Override
+ public List<Lifecycle> get() {
+ synchronized (events) {
+ return Lists.newArrayList(events);
+ }
+ }
+ }
+
+
+}