Author: kwall Date: Fri Jul 10 08:15:27 2015 New Revision: 1690221 URL: http://svn.apache.org/r1690221 Log: QPID-6634: [Java Broker] Prevent spurious state change event if state change operation changes
* Removed duplicated state change event * Added supported unit test Work done by Lorenz Quack <quack.lor...@gmail.com> and Keith Wall. Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1690221&r1=1690220&r2=1690221&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original) +++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Fri Jul 10 08:15:27 2015 @@ -1170,7 +1170,7 @@ public abstract class AbstractConfigured protected ListenableFuture<Void> attainState() { - State currentState = getState(); + final State currentState = getState(); State desiredState = getDesiredState(); ListenableFuture<Void> returnVal; @@ -1193,13 +1193,12 @@ public abstract class AbstractConfigured public void run() { _attainStateFuture.set(AbstractConfiguredObject.this); + if(getState() != currentState) + { + notifyStateChanged(currentState, getState()); + } } }); - if(getState() != currentState) - { - // TODO - KW - shouldn't I be done after too??? - notifyStateChanged(currentState, getState()); - } } catch (IllegalAccessException e) { @@ -1347,30 +1346,15 @@ public abstract class AbstractConfigured attributeSet(ConfiguredObject.DESIRED_STATE, currentDesiredState, desiredState); - - return doAfter(attainStateIfOpenedOrReopenFailed(),new Runnable() - { - @Override - public void run() - { - if (getState() == desiredState) - { - notifyStateChanged(state, desiredState); - } - - } - } - ); + return attainStateIfOpenedOrReopenFailed(); } else { return Futures.immediateFuture(null); } } - } }); - } @Override Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java?rev=1690221&r1=1690220&r2=1690221&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java (original) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/AbstractConfiguredObjectTest.java Fri Jul 10 08:15:27 2015 @@ -19,8 +19,15 @@ package org.apache.qpid.server.model.testmodels.lifecycle; import java.util.Collections; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import com.google.common.util.concurrent.ListenableFuture; import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.ConfigurationChangeListener; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.IllegalStateTransitionException; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.State; import org.apache.qpid.test.utils.QpidTestCase; @@ -214,4 +221,105 @@ public class AbstractConfiguredObjectTes assertEquals("Unexpected child1 state", State.ERRORED, child1.getState()); } + public void testSuccessfulStateTransitionInvokesListener() throws Exception + { + TestConfiguredObject parent = new TestConfiguredObject("parent"); + parent.create(); + + final AtomicReference<State> newState = new AtomicReference<>(); + final AtomicInteger callCounter = new AtomicInteger(); + parent.addChangeListener(new NoopChangeListener() + { + @Override + public void stateChanged(final ConfiguredObject<?> object, final State old, final State state) + { + super.stateChanged(object, old, state); + callCounter.incrementAndGet(); + newState.set(state); + } + }); + + parent.delete(); + assertEquals(State.DELETED, newState.get()); + assertEquals(1, callCounter.get()); + } + + public void testUnsuccessfulStateTransitionDoesnotInvokesListener() throws Exception + { + final IllegalStateTransitionException expectedException = + new IllegalStateTransitionException("This test fails the state transition."); + TestConfiguredObject parent = new TestConfiguredObject("parent") + { + @Override + protected ListenableFuture<Void> doDelete() + { + throw expectedException; + } + }; + parent.create(); + + final AtomicInteger callCounter = new AtomicInteger(); + parent.addChangeListener(new NoopChangeListener() + { + @Override + public void stateChanged(final ConfiguredObject<?> object, final State old, final State state) + { + super.stateChanged(object, old, state); + callCounter.incrementAndGet(); + } + }); + + try + { + parent.delete(); + fail("Exception not thrown."); + } + catch (RuntimeException e) + { + assertSame("State transition threw unexpected exception.", expectedException, e); + } + assertEquals(0, callCounter.get()); + } + + private static class NoopChangeListener implements ConfigurationChangeListener + { + @Override + public void stateChanged(final ConfiguredObject<?> object, final State oldState, final State newState) + { + + } + + @Override + public void childAdded(final ConfiguredObject<?> object, final ConfiguredObject<?> child) + { + + } + + @Override + public void childRemoved(final ConfiguredObject<?> object, final ConfiguredObject<?> child) + { + + } + + @Override + public void attributeSet(final ConfiguredObject<?> object, + final String attributeName, + final Object oldAttributeValue, + final Object newAttributeValue) + { + + } + + @Override + public void bulkChangeStart(final ConfiguredObject<?> object) + { + + } + + @Override + public void bulkChangeEnd(final ConfiguredObject<?> object) + { + + } + } } Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java?rev=1690221&r1=1690220&r2=1690221&view=diff ============================================================================== --- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java (original) +++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/lifecycle/TestConfiguredObject.java Fri Jul 10 08:15:27 2015 @@ -146,13 +146,13 @@ public class TestConfiguredObject extend return Futures.immediateFuture(null); } - @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.DELETED ) + @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED, State.ACTIVE}, desiredState = State.DELETED ) protected ListenableFuture<Void> doDelete() { setState(State.DELETED); return Futures.immediateFuture(null); } - + public boolean isOpened() { return _opened; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org