You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/10/19 09:00:07 UTC
[1/2] brooklyn-server git commit: Fix ManagementNodeStateListener
Repository: brooklyn-server
Updated Branches:
refs/heads/master 38de52240 -> b9a657258
Fix ManagementNodeStateListener
Wait for rebind to complete before notifying of ‘MASTER’
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/749f41ac
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/749f41ac
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/749f41ac
Branch: refs/heads/master
Commit: 749f41ac7bf0ecae0b4a3e28e572da438c3fc833
Parents: efa4af6
Author: Aled Sage <al...@gmail.com>
Authored: Thu Oct 5 10:07:26 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Oct 17 14:27:13 2017 +0100
----------------------------------------------------------------------
.../api/mgmt/ha/HighAvailabilityManager.java | 2 +-
.../mgmt/ha/HighAvailabilityManagerImpl.java | 14 +-
.../ManagementNodeStateListenerManager.java | 70 +++++++
.../NonDeploymentManagementContext.java | 3 +-
.../core/mgmt/rebind/RebindTestFixture.java | 9 +-
.../core/mgmt/rebind/RebindTestUtils.java | 51 ++++-
.../usage/ManagementNodeStateListenerTest.java | 62 ++++--
.../brooklyn/launcher/common/BasicLauncher.java | 3 +-
.../BrooklynEntityMirrorIntegrationTest.java | 2 +-
...erRebindManagementNodeStateListenerTest.java | 199 +++++++++++++++++++
.../rest/testing/BrooklynRestApiTest.java | 2 +-
.../brooklyn/rest/BrooklynRestApiLauncher.java | 5 +-
.../entity/AbstractMultiDistroLiveTest.java | 2 +-
...ftwareProcessRebindNotRunningEntityTest.java | 6 +-
14 files changed, 389 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/HighAvailabilityManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/HighAvailabilityManager.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/HighAvailabilityManager.java
index 6724a03..76002cd 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/HighAvailabilityManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/ha/HighAvailabilityManager.java
@@ -67,7 +67,7 @@ public interface HighAvailabilityManager {
* this is called after this HA Manager is started.
*/
@Beta
- void disabled();
+ void disabled(boolean persistenceEnabled);
/** Whether HA mode is operational */
boolean isRunning();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java
index 0148275..ec00896 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java
@@ -62,6 +62,7 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.internal.ManagementTransitionMode;
import org.apache.brooklyn.core.mgmt.persist.BrooklynPersistenceUtils;
import org.apache.brooklyn.core.mgmt.persist.BrooklynPersistenceUtils.CreateBackupMode;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
import org.apache.brooklyn.core.mgmt.persist.PersistenceActivityMetrics;
import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
import org.apache.brooklyn.core.mgmt.usage.ManagementNodeStateListener;
@@ -145,6 +146,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
private volatile Ticker optionalRemoteTickerUtc = null;
private volatile Task<?> pollingTask;
+ private volatile boolean persistenceEnabled;
private volatile boolean disabled;
private volatile boolean running;
private volatile ManagementNodeState nodeState = ManagementNodeState.INITIALIZING;
@@ -250,7 +252,8 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
}
@Override
- public void disabled() {
+ public void disabled(boolean persistenceEnabled) {
+ this.persistenceEnabled = persistenceEnabled;
disabled = true;
// this is notionally the master, just not running; see javadoc for more info
setNodeStateTransitionComplete(true);
@@ -261,6 +264,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
@Override
public void start(HighAvailabilityMode startMode) {
setNodeStateTransitionComplete(true);
+ persistenceEnabled = true;
disabled = false;
running = true;
changeMode(startMode, true, true);
@@ -527,8 +531,12 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
nodeStateHistory.remove(nodeStateHistory.size()-1);
}
}
- ((RebindManagerImpl)managementContext.getRebindManager()).setAwaitingInitialRebind(running &&
- (ManagementNodeState.isHotProxy(newState) || newState==ManagementNodeState.MASTER));
+ // If no HA (i.e. a standalone server) then we will be 'disabled'. We will still be
+ // queried for `getNodeState()` and therefore still want to record awaiting-initial-rebind
+ // if this standalone server has persistence enabled.
+ boolean awaitingInitialRebind = (running || (disabled && persistenceEnabled)) &&
+ (ManagementNodeState.isHotProxy(newState) || newState==ManagementNodeState.MASTER);
+ ((RebindManagerImpl)managementContext.getRebindManager()).setAwaitingInitialRebind(awaitingInitialRebind);
this.nodeState = newState;
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementNodeStateListenerManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementNodeStateListenerManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementNodeStateListenerManager.java
index e148c7b..729105f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementNodeStateListenerManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementNodeStateListenerManager.java
@@ -26,6 +26,7 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
@@ -61,6 +62,9 @@ public class ManagementNodeStateListenerManager implements ManagementNodeStateLi
private final ManagementContextInternal mgmt;
private final Object mutex = new Object();
+ private final Object waitForMasterRebindMutex = new Object();
+
+ private volatile boolean terminated;
private final List<ManagementNodeStateListener> listeners = Lists.newCopyOnWriteArrayList();
private ManagementNodeState lastPublishedVal;
@@ -105,6 +109,10 @@ public class ManagementNodeStateListenerManager implements ManagementNodeStateLi
@Override
public void onStateChange(ManagementNodeState state) {
// Filtering out duplicates/nulls, schedule the notification of the listeners with this latest value.
+ //
+ // If transitioning to master, also ensure we have finished rebinding to the persisted state
+ // (see comments in waitForMasterNotRebinding).
+
synchronized (mutex) {
if (state != null && lastPublishedVal != state) {
LOG.debug("Notifying {} listener(s) of management-node state changed to {}", new Object[] {listeners.size(), state});
@@ -112,6 +120,14 @@ public class ManagementNodeStateListenerManager implements ManagementNodeStateLi
execOnListeners(new Function<ManagementNodeStateListener, Void>() {
@Override
public Void apply(ManagementNodeStateListener listener) {
+ if (state == ManagementNodeState.MASTER) {
+ boolean success = waitForMasterNotRebinding();
+ if (!success) {
+ LOG.info("Not notifying listener {} of management-node state {} because did not finish rebinding",
+ new Object[] {listener, state});
+ return null;
+ }
+ }
listener.onStateChange(state);
return null;
}
@@ -123,7 +139,61 @@ public class ManagementNodeStateListenerManager implements ManagementNodeStateLi
}
}
+ /**
+ * If we have transitioned to master, ensure that we have also finished rebinding to persisted state.
+ * This is important so that a listener can list the apps etc.
+ *
+ * While waiting, it will abort if we are terminated or if the state transitions away from being master
+ * (e.g. rebind fails).
+ *
+ * @return true if we are still rebind completes are we are still master; false otherwise.
+ */
+ private boolean waitForMasterNotRebinding() {
+ // This approach feels very hacky, but it's hard to do better: the internal state of Brooklyn is
+ // buried inside HighAvailabilityManager and RebindManager; their behaviours depend on the sequence
+ // of calls made to each (e.g. controlled by `BasicLauncher`).
+ //
+ // For example, if the haManager promotes us to master, it will mark its state as 'MASTER' before rebind
+ // (i.e. the RebindManager will not yet have been given the persisted state, so we won't know about our
+ // apps/catalog yet). To work around this, the haManager calls `RebindManagerImpl.setAwaitingInitialRebind`.
+ // Where required, one can therefore call `RebindManager.isAwaitingInitialRebind()` to find out if we
+ // are properly initialized. The REST api does this in its 'HaHotCheck' filter.
+ //
+ // if HA is disabled, then `highAvailabilityManager.disable()` will mark its state as 'MASTER' (because
+ // it will obviously be the only node in that HA-cluster). If persistence is disabled, that's fine.
+ // But if persistence is enabled, then the RebindManager will not yet have been given the persisted state.
+ // The haManager therefore also now calls setAwaitingInitialRebind in this situation.
+ // For how the REST api behaves, it will report 'MASTER' before rebind is done. However, /server/healthy
+ // will continue to say false until rebind is complete. This is because the `BasicLauncher` will be rebinding
+ // to the persisted state synchronously: it will only mark the management context as 'startup-complete' after
+ // rebind (via the call to LocalManagementContext.noteStartupComplete).
+
+ while (true) {
+ boolean awaitingRebind = mgmt.getRebindManager().isAwaitingInitialRebind();
+ ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
+ boolean abort = (state != ManagementNodeState.MASTER) || terminated || !mgmt.isRunning();
+
+ if (abort) {
+ return false;
+ } else if (!awaitingRebind) {
+ return true;
+ }
+ synchronized (waitForMasterRebindMutex) {
+ try {
+ waitForMasterRebindMutex.wait(100);
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+ }
+ }
+
public void terminate() {
+ terminated = true;
+ synchronized (waitForMasterRebindMutex) {
+ waitForMasterRebindMutex.notifyAll();
+ }
+
// Wait for the listeners to finish + close the listeners
Duration timeout = mgmt.getBrooklynProperties().getConfig(BrooklynServerConfig.MANAGEMENT_NODE_STATE_LISTENER_TERMINATION_TIMEOUT);
if (listenerQueueSize.get() > 0) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
index b5fd0b5..a1ab3df 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
@@ -67,6 +67,7 @@ import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
import org.apache.brooklyn.core.mgmt.usage.UsageManager;
import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
import org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
@@ -629,7 +630,7 @@ public class NonDeploymentManagementContext implements ManagementContextInternal
throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
}
@Override
- public void disabled() {
+ public void disabled(boolean persistenceEnabled) {
throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
}
@Override
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
index bad753d..42fdc70 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
@@ -296,12 +296,11 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
return newApp;
}
- protected T hotStandby() throws Exception {
+ protected ManagementContext hotStandby() throws Exception {
return hotStandby(RebindOptions.create());
}
- @SuppressWarnings("unchecked")
- protected T hotStandby(RebindOptions options) throws Exception {
+ protected ManagementContext hotStandby(RebindOptions options) throws Exception {
if (newApp != null || newManagementContext != null) {
throw new IllegalStateException("already rebound - use switchOriginalToNewManagementContext() if you are trying to rebind multiple times");
}
@@ -323,8 +322,8 @@ public abstract class RebindTestFixture<T extends StartableApplication> {
RebindTestUtils.stopPersistence(origApp);
newManagementContext = options.newManagementContext;
- newApp = (T) RebindTestUtils.rebind(options);
- return newApp;
+ RebindTestUtils.rebind(options);
+ return newManagementContext;
}
/**
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
index 911db07..428858b 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
@@ -31,8 +31,10 @@ import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecordPersister;
import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMemento;
@@ -290,10 +292,11 @@ public class RebindTestUtils {
if (persistMode == PersistMode.DISABLED) {
unstarted.generateManagementPlaneId();
unstarted.getCatalogInitialization().populateInitialCatalogOnly();
+ unstarted.getHighAvailabilityManager().disabled(persistMode != PersistMode.DISABLED);
} else if (haMode == HighAvailabilityMode.DISABLED) {
unstarted.getRebindManager().rebind(classLoader, null, ManagementNodeState.MASTER);
unstarted.getRebindManager().startPersistence();
- unstarted.getHighAvailabilityManager().disabled();
+ unstarted.getHighAvailabilityManager().disabled(persistMode != PersistMode.DISABLED);
} else {
unstarted.getHighAvailabilityManager().start(haMode);
}
@@ -388,7 +391,11 @@ public class RebindTestUtils {
}
Collection<Application> newApps = rebindAll(options);
if (newApps.isEmpty()) {
- if (hadApps) {
+ if (options.haMode != null && options.haMode != HighAvailabilityMode.DISABLED) {
+ // will rebind async, when promoted to master.
+ // Dont't assert here! Rely on caller to wait.
+ return null;
+ } else if (hadApps) {
throw new IllegalStateException("Application could not be found after rebind; serialization probably failed");
} else {
// no apps before; probably testing catalog
@@ -469,6 +476,7 @@ public class RebindTestUtils {
HighAvailabilityMode haMode = (options.haMode == null ? HighAvailabilityMode.DISABLED : options.haMode);
RebindExceptionHandler exceptionHandler = options.exceptionHandler;
boolean hasPersister = newManagementContext != null && newManagementContext.getRebindManager().getPersister() != null;
+ boolean hasHaPersister = newManagementContext != null && newManagementContext.getHighAvailabilityManager().getPersister() != null;
boolean checkSerializable = options.checkSerializable;
boolean terminateOrigManagementContext = options.terminateOrigManagementContext;
Function<BrooklynMementoPersister, Void> stateTransformer = options.stateTransformer;
@@ -517,12 +525,39 @@ public class RebindTestUtils {
stateTransformer.apply(persister);
}
- List<Application> newApps = newManagementContext.getRebindManager().rebind(
- classLoader,
- exceptionHandler,
- (haMode == HighAvailabilityMode.DISABLED) ? ManagementNodeState.MASTER : ManagementNodeState.of(haMode).get());
- newManagementContext.getRebindManager().startPersistence();
- return newApps;
+ if (haMode == HighAvailabilityMode.DISABLED) {
+ HighAvailabilityManager haManager = newManagementContext.getHighAvailabilityManager();
+ haManager.disabled(true);
+
+ List<Application> newApps = newManagementContext.getRebindManager().rebind(
+ classLoader,
+ exceptionHandler,
+ (haMode == HighAvailabilityMode.DISABLED) ? ManagementNodeState.MASTER : ManagementNodeState.of(haMode).get());
+ newManagementContext.getRebindManager().startPersistence();
+
+ return newApps;
+
+ } else {
+ HighAvailabilityManager haManager = newManagementContext.getHighAvailabilityManager();
+
+ if (!hasHaPersister) {
+ if (hasPersister) throw new IllegalStateException("Must not supply persister for RebindManager but not for HighAvailabilityManager");
+ assert objectStore != null;
+
+ ManagementPlaneSyncRecordPersister persister =
+ new ManagementPlaneSyncRecordPersisterToObjectStore(newManagementContext,
+ objectStore,
+ newManagementContext.getCatalogClassLoader());
+
+ haManager.setPersister(persister);
+ }
+
+ haManager.start(haMode);
+
+ // TODO We'll be promoted to master asynchronously; will not yet have done our rebind.
+ // Could block here for rebind to complete but do any callers really need us to do that?
+ return ImmutableList.of();
+ }
}
public static void waitForPersisted(Application origApp) throws InterruptedException, TimeoutException {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/core/src/test/java/org/apache/brooklyn/core/mgmt/usage/ManagementNodeStateListenerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/usage/ManagementNodeStateListenerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/usage/ManagementNodeStateListenerTest.java
index 0c1e07b..e5dc961 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/usage/ManagementNodeStateListenerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/usage/ManagementNodeStateListenerTest.java
@@ -27,8 +27,10 @@ import static org.testng.Assert.assertTrue;
import java.util.List;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
@@ -62,7 +64,7 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
// Need to call HighAvailabilityManager explicitly; otherwise it will never publish
// the ManagementNodeState.
LocalManagementContext result = LocalManagementContextForTests.newInstance(brooklynProperties);
- result.getHighAvailabilityManager().disabled();
+ result.getHighAvailabilityManager().disabled(false);
result.noteStartupComplete();
return result;
}
@@ -73,10 +75,11 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
brooklynProperties.put(BrooklynServerConfig.MANAGEMENT_NODE_STATE_LISTENERS, ImmutableList.of(new RecordingStaticManagementNodeStateListener()));
replaceManagementContext(newManagementContext(brooklynProperties));
- assertEventsEventually(RecordingStaticManagementNodeStateListener.getInstance(), ImmutableList.of(INITIALIZING, MASTER));
+ assertEquals(RecordingStaticManagementNodeStateListener.getInstance().getManagementContext(), mgmt);
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
mgmt.terminate();
- assertEventsEventually(RecordingStaticManagementNodeStateListener.getInstance(), ImmutableList.of(INITIALIZING, MASTER, TERMINATED));
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER, TERMINATED));
}
@Test
@@ -85,7 +88,7 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
brooklynProperties.put(BrooklynServerConfig.MANAGEMENT_NODE_STATE_LISTENERS, RecordingStaticManagementNodeStateListener.class.getName());
replaceManagementContext(newManagementContext(brooklynProperties));
- assertEventsEventually(RecordingStaticManagementNodeStateListener.getInstance(), ImmutableList.of(INITIALIZING, MASTER));
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
}
@Test
@@ -99,8 +102,8 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
assertTrue(listeners.get(0) instanceof RecordingStaticManagementNodeStateListener, "listeners="+listeners);
assertTrue(listeners.get(1) instanceof RecordingStaticManagementNodeStateListener, "listeners="+listeners);
- assertEventsEventually(listeners.get(0), ImmutableList.of(INITIALIZING, MASTER));
- assertEventsEventually(listeners.get(1), ImmutableList.of(INITIALIZING, MASTER));
+ listeners.get(0).assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
+ listeners.get(1).assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
}
@Test(expectedExceptions = ClassCastException.class)
@@ -110,15 +113,6 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
replaceManagementContext(LocalManagementContextForTests.newInstance(brooklynProperties));
}
- private void assertEventsEventually(RecordingManagementNodeStateListener listener, List<ManagementNodeState> expected) {
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- List<ManagementNodeState> actual = listener.getEvents();
- String errMsg = "actual="+actual+"; expected="+expected;
- assertEquals(actual, expected, errMsg);
- }});
- }
-
public static class RecordingStaticManagementNodeStateListener extends RecordingManagementNodeStateListener implements ManagementNodeStateListener {
private static final List<RecordingStaticManagementNodeStateListener> STATIC_INSTANCES = Lists.newCopyOnWriteArrayList();
@@ -126,6 +120,14 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
return Iterables.getOnlyElement(STATIC_INSTANCES);
}
+ public static RecordingStaticManagementNodeStateListener getInstanceEventually() {
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ assertTrue(STATIC_INSTANCES.size() > 0);
+ }});
+ return getInstance();
+ }
+
public static RecordingStaticManagementNodeStateListener getLastInstance() {
return Iterables.getLast(STATIC_INSTANCES);
}
@@ -145,10 +147,16 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
}
}
- public static class RecordingManagementNodeStateListener implements ManagementNodeStateListener {
+ public static class RecordingManagementNodeStateListener implements ManagementNodeStateListener, ManagementContextInjectable {
private final List<ManagementNodeState> events = Lists.newCopyOnWriteArrayList();
+ private ManagementContext managementContext;
@Override
+ public void setManagementContext(ManagementContext managementContext) {
+ this.managementContext = managementContext;
+ }
+
+ @Override
public void onStateChange(ManagementNodeState state) {
events.add(state);
}
@@ -156,5 +164,27 @@ public class ManagementNodeStateListenerTest extends BrooklynMgmtUnitTestSupport
public List<ManagementNodeState> getEvents() {
return ImmutableList.copyOf(events);
}
+
+ public ManagementContext getManagementContext() {
+ return managementContext;
+ }
+
+ public void assertEventsEventually(List<ManagementNodeState> expected) {
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ List<ManagementNodeState> actual = getEvents();
+ String errMsg = "actual="+actual+"; expected="+expected;
+ assertEquals(actual, expected, errMsg);
+ }});
+ }
+
+ public void assertEventsContinually(List<ManagementNodeState> expected) {
+ Asserts.succeedsContinually(new Runnable() {
+ public void run() {
+ List<ManagementNodeState> actual = getEvents();
+ String errMsg = "actual="+actual+"; expected="+expected;
+ assertEquals(actual, expected, errMsg);
+ }});
+ }
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
----------------------------------------------------------------------
diff --git a/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java b/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
index 19b6e20..ddb3f8e 100644
--- a/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
+++ b/launcher-common/src/main/java/org/apache/brooklyn/launcher/common/BasicLauncher.java
@@ -439,6 +439,7 @@ public class BasicLauncher<T extends BasicLauncher<T>> {
} else {
((LocalManagementContext)managementContext).generateManagementPlaneId();
populateInitialCatalogNoPersistence(catalogInitialization);
+ managementContext.getHighAvailabilityManager().disabled(false);
}
markCatalogStarted(catalogInitialization);
addLocations();
@@ -614,7 +615,7 @@ public class BasicLauncher<T extends BasicLauncher<T>> {
// Now start the HA Manager and the Rebind manager, as required
if (highAvailabilityMode == HighAvailabilityMode.DISABLED) {
HighAvailabilityManager haManager = managementContext.getHighAvailabilityManager();
- haManager.disabled();
+ haManager.disabled(true);
startPersistenceWithoutHA();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java b/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java
index 3c874f8..a665149 100644
--- a/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java
@@ -88,7 +88,7 @@ public class BrooklynEntityMirrorIntegrationTest {
server.skipSecurity(skipSecurity);
server.start();
- serverMgmt.getHighAvailabilityManager().disabled();
+ serverMgmt.getHighAvailabilityManager().disabled(false);
serverApp = TestApplication.Factory.newManagedInstanceForTests(serverMgmt);
((LocalManagementContextForTests)serverMgmt).noteStartupComplete();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindManagementNodeStateListenerTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindManagementNodeStateListenerTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindManagementNodeStateListenerTest.java
new file mode 100644
index 0000000..e417bbc
--- /dev/null
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindManagementNodeStateListenerTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.launcher;
+
+import static org.apache.brooklyn.api.mgmt.ha.ManagementNodeState.INITIALIZING;
+import static org.apache.brooklyn.api.mgmt.ha.ManagementNodeState.MASTER;
+import static org.apache.brooklyn.api.mgmt.ha.ManagementNodeState.STANDBY;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
+import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.persist.PersistMode;
+import org.apache.brooklyn.core.mgmt.usage.ManagementNodeStateListenerTest.RecordingStaticManagementNodeStateListener;
+import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class BrooklynLauncherRebindManagementNodeStateListenerTest extends AbstractBrooklynLauncherRebindTest {
+
+ private AtomicReference<CountDownLatch> populateInitialCatalogOnlyLatch = new AtomicReference<>();
+ private AtomicReference<CountDownLatch> populateInitialAndPersistedCatalogLatch = new AtomicReference<>();
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ RecordingStaticManagementNodeStateListener.clearInstances();
+ populateInitialCatalogOnlyLatch.set(null);
+ populateInitialAndPersistedCatalogLatch.set(null);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ RecordingStaticManagementNodeStateListener.clearInstances();
+ }
+
+ @Override
+ protected BrooklynLauncher newLauncherForTests(PersistMode persistMode, HighAvailabilityMode haMode) {
+ BrooklynProperties brooklynProperties = LocalManagementContextForTests.builder(true).buildProperties();
+ brooklynProperties.put(BrooklynServerConfig.MANAGEMENT_NODE_STATE_LISTENERS, RecordingStaticManagementNodeStateListener.class.getName());
+
+ // If latches are set, then blocks startup
+ CatalogInitialization catInit = new CatalogInitialization() {
+ @Override
+ public void populateInitialAndPersistedCatalog(ManagementNodeState mode, PersistedCatalogState persistedState, RebindExceptionHandler exceptionHandler, RebindLogger rebindLogger) {
+ awaitIfNotNull(populateInitialAndPersistedCatalogLatch);
+ super.populateInitialAndPersistedCatalog(mode, persistedState, exceptionHandler, rebindLogger);
+ }
+ @Override
+ public void populateInitialCatalogOnly() {
+ awaitIfNotNull(populateInitialCatalogOnlyLatch);
+ super.populateInitialCatalogOnly();
+ }
+ private void awaitIfNotNull(AtomicReference<CountDownLatch> latchRef) {
+ CountDownLatch latch = latchRef.get();
+ if (latch != null) {
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+ }
+ };
+
+ return super.newLauncherForTests(persistMode, haMode)
+ .brooklynProperties(brooklynProperties)
+ .catalogInitialization(catInit);
+ }
+
+ @Test
+ public void testNotifiesWhenPersistenceOff() throws Exception {
+ BrooklynLauncher launcher = newLauncherForTests(PersistMode.DISABLED, HighAvailabilityMode.DISABLED);
+ launcher.start();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
+ }
+
+ @Test
+ public void testNotifiesOnRebind() throws Exception {
+ // Starting with no persisted state
+ BrooklynLauncher launcher = newLauncherForTests();
+ launcher.start();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
+ RecordingStaticManagementNodeStateListener.clearInstances();
+
+ launcher.terminate();
+
+ // Starting with a populated persisted state dir
+ BrooklynLauncher newLauncher = newLauncherForTests();
+ newLauncher.start();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, MASTER));
+ }
+
+ @Test
+ public void testNotifiesOnHighAvailabilityPromotion() throws Exception {
+ // Start master
+ BrooklynLauncher launcher = newLauncherForTests(PersistMode.AUTO, HighAvailabilityMode.AUTO);
+ launcher.start();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, STANDBY, MASTER));
+ RecordingStaticManagementNodeStateListener.clearInstances();
+
+ // Start standby
+ BrooklynLauncher launcher2 = newLauncherForTests(PersistMode.AUTO, HighAvailabilityMode.AUTO);
+ launcher2.start();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, STANDBY));
+
+ // Promote standby to master
+ launcher.terminate();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(ImmutableList.of(INITIALIZING, STANDBY, MASTER));
+ }
+
+ @Test
+ public void testNotifiesOfMasterOnlyAfterRebindingAppsWhenHaDisabled() throws Exception {
+ runNotifiesOfMasterOnlyAfterRebindingApps(HighAvailabilityMode.DISABLED);
+ }
+
+ @Test
+ public void testNotifiesOfMasterOnlyAfterRebindingAppsWhenHaEnabled() throws Exception {
+ runNotifiesOfMasterOnlyAfterRebindingApps(HighAvailabilityMode.AUTO);
+ }
+
+ protected void runNotifiesOfMasterOnlyAfterRebindingApps(HighAvailabilityMode haMode) throws Exception {
+ // Populate the persisted state with an app
+ BrooklynLauncher origLauncher = newLauncherForTests(PersistMode.AUTO, haMode);
+ origLauncher.start();
+ TestApplication origApp = origLauncher.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestApplication.class));
+ origLauncher.terminate();
+ RecordingStaticManagementNodeStateListener.clearInstances();
+
+ // Start an app async (causing its rebind to block until we release the latch)
+ populateInitialAndPersistedCatalogLatch.set(new CountDownLatch(1));
+
+ BrooklynLauncher launcher2 = newLauncherForTests(PersistMode.AUTO, haMode);
+ Thread t = new Thread() {
+ public void run() {
+ launcher2.start();
+ }
+ };
+ try {
+ List<ManagementNodeState> expectedInitialStates = (haMode == HighAvailabilityMode.DISABLED) ?
+ ImmutableList.of(INITIALIZING) :
+ ImmutableList.of(INITIALIZING, STANDBY);
+ List<ManagementNodeState> expectedFinalStates = (haMode == HighAvailabilityMode.DISABLED) ?
+ ImmutableList.of(INITIALIZING, MASTER) :
+ ImmutableList.of(INITIALIZING, STANDBY, MASTER);
+
+ t.start();
+ RecordingStaticManagementNodeStateListener.getInstanceEventually().assertEventsEventually(expectedInitialStates);
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsContinually(expectedInitialStates);
+ assertTrue(t.isAlive());
+
+ // Let it complete; now expect to get the callback that we are master
+ populateInitialAndPersistedCatalogLatch.get().countDown();
+ RecordingStaticManagementNodeStateListener.getInstance().assertEventsEventually(expectedFinalStates);
+ Application newApp = Iterables.getOnlyElement(launcher2.getManagementContext().getApplications());
+ assertEquals(newApp.getId(), origApp.getId());
+
+ t.join(Asserts.DEFAULT_LONG_TIMEOUT.toMilliseconds());
+ } finally {
+ t.interrupt();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
index 2ae0183..54c9384 100644
--- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
@@ -147,7 +147,7 @@ public abstract class BrooklynRestApiTest {
} else {
manager = new LocalManagementContextForTests();
}
- manager.getHighAvailabilityManager().disabled();
+ manager.getHighAvailabilityManager().disabled(false);
((LocalManagementContext)manager).generateManagementPlaneId();
new BrooklynCampPlatformLauncherNoServer()
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
index b7c6b2e..617fb77 100644
--- a/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/rest/rest-server/src/test/java/org/apache/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -304,8 +304,9 @@ public class BrooklynRestApiLauncher {
((BrooklynProperties)mgmt.getConfig()).put(BrooklynWebConfig.SECURITY_PROVIDER_CLASSNAME, AnyoneSecurityProvider.class.getName());
}
}
- if (mgmt != null && disableHighAvailability)
- mgmt.getHighAvailabilityManager().disabled();
+ if (mgmt != null && disableHighAvailability) {
+ mgmt.getHighAvailabilityManager().disabled(false);
+ }
InetSocketAddress bindLocation = new InetSocketAddress(
secure ? Networking.ANY_NIC : Networking.LOOPBACK,
Networking.nextAvailablePort(FAVOURITE_PORT));
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/software/base/src/test/java/org/apache/brooklyn/entity/AbstractMultiDistroLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/AbstractMultiDistroLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/AbstractMultiDistroLiveTest.java
index fa44f18..ff29408 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/AbstractMultiDistroLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/AbstractMultiDistroLiveTest.java
@@ -97,7 +97,7 @@ public abstract class AbstractMultiDistroLiveTest extends BrooklynAppLiveTestSup
localManagementContextForTests.generateManagementPlaneId();
mgmt = localManagementContextForTests;
- mgmt.getHighAvailabilityManager().disabled();
+ mgmt.getHighAvailabilityManager().disabled(false);
super.setUp();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/749f41ac/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRebindNotRunningEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRebindNotRunningEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRebindNotRunningEntityTest.java
index be591ef..6a58efd 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRebindNotRunningEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessRebindNotRunningEntityTest.java
@@ -32,6 +32,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.ImplementedBy;
@@ -40,6 +41,7 @@ import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.MachineProvisioningLocation;
import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
@@ -319,7 +321,9 @@ public class SoftwareProcessRebindNotRunningEntityTest extends RebindTestFixture
EntityAsserts.assertAttributeEquals(entity, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.STARTING);
// Check that the read-only hot standby does not overwrite the entity's state; it should still say "STARTING"
- TestApplication newApp = hotStandby();
+ ManagementContext newManagementContext = hotStandby();
+ Asserts.succeedsEventually(() -> assertTrue(newManagementContext.getApplications().size() > 0));
+ Application newApp = Iterables.getOnlyElement(newManagementContext.getApplications());
final VanillaSoftwareProcess newEntity = (VanillaSoftwareProcess) Iterables.find(newApp.getChildren(), Predicates.instanceOf(VanillaSoftwareProcess.class));
assertNotMarkedOnfire(newEntity, Lifecycle.STARTING);
[2/2] brooklyn-server git commit: This closes #863
Posted by dr...@apache.org.
This closes #863
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/b9a65725
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/b9a65725
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/b9a65725
Branch: refs/heads/master
Commit: b9a6572585e7e366b85af1ad0812c2f8f2e9727b
Parents: 38de522 749f41a
Author: Duncan Godwin <dr...@googlemail.com>
Authored: Thu Oct 19 09:59:55 2017 +0100
Committer: Duncan Godwin <dr...@googlemail.com>
Committed: Thu Oct 19 09:59:55 2017 +0100
----------------------------------------------------------------------
.../api/mgmt/ha/HighAvailabilityManager.java | 2 +-
.../mgmt/ha/HighAvailabilityManagerImpl.java | 14 +-
.../ManagementNodeStateListenerManager.java | 70 +++++++
.../NonDeploymentManagementContext.java | 3 +-
.../core/mgmt/rebind/RebindTestFixture.java | 9 +-
.../core/mgmt/rebind/RebindTestUtils.java | 51 ++++-
.../usage/ManagementNodeStateListenerTest.java | 62 ++++--
.../brooklyn/launcher/common/BasicLauncher.java | 3 +-
.../BrooklynEntityMirrorIntegrationTest.java | 2 +-
...erRebindManagementNodeStateListenerTest.java | 199 +++++++++++++++++++
.../rest/testing/BrooklynRestApiTest.java | 2 +-
.../brooklyn/rest/BrooklynRestApiLauncher.java | 5 +-
.../entity/AbstractMultiDistroLiveTest.java | 2 +-
...ftwareProcessRebindNotRunningEntityTest.java | 6 +-
14 files changed, 389 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b9a65725/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b9a65725/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b9a65725/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestUtils.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/b9a65725/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorIntegrationTest.java
----------------------------------------------------------------------