From 90016f4f1701827145f93820de4587df53b1594d Mon Sep 17 00:00:00 2001 From: Ensar Basri Kahveci Date: Thu, 29 Dec 2016 15:16:07 +0300 Subject: [PATCH] Fire STARTING lifecycle event after listeners are registered Fixes #9189 --- .../instance/HazelcastInstanceImpl.java | 3 +- .../java/com/hazelcast/instance/Node.java | 2 + .../instance/LifeCycleListenerTest.java | 58 ++++++++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/hazelcast/src/main/java/com/hazelcast/instance/HazelcastInstanceImpl.java b/hazelcast/src/main/java/com/hazelcast/instance/HazelcastInstanceImpl.java index c5c58513bc9f..e90718a5c816 100644 --- a/hazelcast/src/main/java/com/hazelcast/instance/HazelcastInstanceImpl.java +++ b/hazelcast/src/main/java/com/hazelcast/instance/HazelcastInstanceImpl.java @@ -89,7 +89,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static com.hazelcast.core.LifecycleEvent.LifecycleState.STARTING; import static com.hazelcast.util.Preconditions.checkNotNull; @PrivateApi @@ -132,9 +131,9 @@ protected HazelcastInstanceImpl(String name, Config config, NodeContext nodeCont try { logger = node.getLogger(getClass().getName()); - lifecycleService.fireLifecycleEvent(STARTING); node.start(); + if (!node.isRunning()) { throw new IllegalStateException("Node failed to start!"); } diff --git a/hazelcast/src/main/java/com/hazelcast/instance/Node.java b/hazelcast/src/main/java/com/hazelcast/instance/Node.java index 2f591066c50c..0d04fa693bc6 100644 --- a/hazelcast/src/main/java/com/hazelcast/instance/Node.java +++ b/hazelcast/src/main/java/com/hazelcast/instance/Node.java @@ -30,6 +30,7 @@ import com.hazelcast.core.ClientListener; import com.hazelcast.core.DistributedObjectListener; import com.hazelcast.core.HazelcastInstanceAware; +import com.hazelcast.core.LifecycleEvent.LifecycleState; import com.hazelcast.core.LifecycleListener; import com.hazelcast.core.MembershipListener; import com.hazelcast.core.MigrationListener; @@ -371,6 +372,7 @@ public void setMasterAddress(final Address master) { void start() { nodeEngine.start(); initializeListeners(config); + hazelcastInstance.lifecycleService.fireLifecycleEvent(LifecycleState.STARTING); connectionManager.start(); if (config.getNetworkConfig().getJoin().getMulticastConfig().isEnabled()) { final Thread multicastServiceThread = new Thread( diff --git a/hazelcast/src/test/java/com/hazelcast/instance/LifeCycleListenerTest.java b/hazelcast/src/test/java/com/hazelcast/instance/LifeCycleListenerTest.java index 0a219143d08e..01d97dae7326 100644 --- a/hazelcast/src/test/java/com/hazelcast/instance/LifeCycleListenerTest.java +++ b/hazelcast/src/test/java/com/hazelcast/instance/LifeCycleListenerTest.java @@ -19,7 +19,9 @@ import com.hazelcast.config.Config; import com.hazelcast.config.ListenerConfig; import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.LifecycleEvent; +import com.hazelcast.core.LifecycleEvent.LifecycleState; import com.hazelcast.core.LifecycleListener; import com.hazelcast.test.HazelcastSerialClassRunner; import com.hazelcast.test.HazelcastTestSupport; @@ -29,9 +31,12 @@ import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(HazelcastSerialClassRunner.class) @@ -48,6 +53,45 @@ public void testListenerNoDeadLock() throws Exception { assertTrue(latch.await(10, TimeUnit.SECONDS)); } + @Test + public void testListenerInvocationWhenNodeStarts() { + TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); + final Config config = new Config(); + final EventCountingListener listener = new EventCountingListener(); + config.addListenerConfig(new ListenerConfig(listener)); + factory.newHazelcastInstance(config); + assertEquals(LifecycleState.STARTING, listener.events.get(0)); + assertEquals(LifecycleState.STARTED, listener.events.get(1)); + } + + @Test + public void testListenerInvocationWhenNodeShutsDown() { + TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); + final Config config = new Config(); + final EventCountingListener listener = new EventCountingListener(); + config.addListenerConfig(new ListenerConfig(listener)); + HazelcastInstance instance = factory.newHazelcastInstance(config); + + listener.events.clear(); + instance.getLifecycleService().shutdown(); + assertEquals(LifecycleState.SHUTTING_DOWN, listener.events.get(0)); + assertEquals(LifecycleState.SHUTDOWN, listener.events.get(1)); + } + + @Test + public void testListenerInvocationWhenNodeTerminates() { + TestHazelcastInstanceFactory factory = createHazelcastInstanceFactory(1); + final Config config = new Config(); + final EventCountingListener listener = new EventCountingListener(); + config.addListenerConfig(new ListenerConfig(listener)); + HazelcastInstance instance = factory.newHazelcastInstance(config); + + listener.events.clear(); + instance.getLifecycleService().terminate(); + assertEquals(LifecycleState.SHUTTING_DOWN, listener.events.get(0)); + assertEquals(LifecycleState.SHUTDOWN, listener.events.get(1)); + } + static class MyLifecycleListener implements LifecycleListener { private CountDownLatch latch; @@ -58,10 +102,22 @@ static class MyLifecycleListener implements LifecycleListener { @Override public void stateChanged(LifecycleEvent event) { - if (event.getState() == LifecycleEvent.LifecycleState.STARTED) { + if (event.getState() == LifecycleState.STARTED) { Hazelcast.getHazelcastInstanceByName("_hzInstance_1_dev"); latch.countDown(); } } } + + static class EventCountingListener implements LifecycleListener { + + private final List events = new CopyOnWriteArrayList(); + + @Override + public void stateChanged(LifecycleEvent event) { + events.add(event.getState()); + } + + } + }