You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2015/08/09 10:13:07 UTC
svn commit: r1694857 - in /qpid/java/trunk/broker-core/src:
main/java/org/apache/qpid/server/model/
test/java/org/apache/qpid/server/model/testmodels/hierarchy/
Author: kwall
Date: Sun Aug 9 08:13:07 2015
New Revision: 1694857
URL: http://svn.apache.org/r1694857
Log:
QPID-6684: [Java Broker] Ensure asynchronous state change exceptions are passed back to caller
* Guarded case 1 - attainState returns a Future containing an exception
* Guarded case 2 - the recursive call to doAttainState returned a future contain a non-RuntimeException
* Refactored to use Futures.allAsList (rather than ChildCounter)
* Added supporting unit test
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/hierarchy/AbstractConfiguredObjectTest.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestKitCarImpl.java
qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestStandardCarImpl.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=1694857&r1=1694856&r2=1694857&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 Sun Aug 9 08:13:07 2015
@@ -542,30 +542,6 @@ public abstract class AbstractConfigured
}
}
- private class ChildCounter
- {
- private final AtomicInteger _count = new AtomicInteger();
- private final Runnable _task;
-
- private ChildCounter(final Runnable task)
- {
- _task = task;
- }
-
- public void incrementCount()
- {
- _count.incrementAndGet();
- }
-
- public void decrementCount()
- {
- if(_count.decrementAndGet() == 0)
- {
- _task.run();
- }
- }
- }
-
protected final ListenableFuture<Void> closeChildren()
{
final List<ListenableFuture<Void>> childCloseFutures = new ArrayList<>();
@@ -587,9 +563,9 @@ public abstract class AbstractConfigured
public void onFailure(final Throwable t)
{
LOGGER.error("Exception occurred while closing {} : {}",
- new Object[] {child.getClass().getSimpleName(),
- child.getName(),
- t});
+ new Object[]{child.getClass().getSimpleName(),
+ child.getName(),
+ t});
}
});
childCloseFutures.add(childCloseFuture);
@@ -795,22 +771,63 @@ public abstract class AbstractConfigured
private ListenableFuture<Void> doAttainState(final AbstractConfiguredObjectExceptionHandler exceptionHandler)
{
+ final List<ListenableFuture<Void>> childStateFutures = new ArrayList<>();
+
+ applyToChildren(new Action<ConfiguredObject<?>>()
+ {
+ @Override
+ public void performAction(final ConfiguredObject<?> child)
+ {
+ if (child instanceof AbstractConfiguredObject
+ && ((AbstractConfiguredObject)child)._dynamicState.get() == DynamicState.OPENED)
+ {
+ final AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child;
+ childStateFutures.add(configuredObject.doAttainState(exceptionHandler));
+
+ }
+ }
+ });
+
+ ListenableFuture<List<Void>> combinedChildStateFuture = Futures.allAsList(childStateFutures);
+
final SettableFuture<Void> returnVal = SettableFuture.create();
- final ChildCounter counter = new ChildCounter(new Runnable()
+ Futures.addCallback(combinedChildStateFuture, new FutureCallback<List<Void>>()
{
@Override
- public void run()
+ public void onSuccess(final List<Void> result)
{
try
{
- attainState().addListener(new Runnable()
- {
- @Override
- public void run()
- {
- returnVal.set(null);
- }
- }, getTaskExecutor().getExecutor());
+ Futures.addCallback(attainState(),
+ new FutureCallback<Void>()
+ {
+ @Override
+ public void onSuccess(final Void result1)
+ {
+ returnVal.set(null);
+ }
+
+ @Override
+ public void onFailure(final Throwable t)
+ {
+ try
+ {
+ if (t instanceof RuntimeException)
+ {
+ exceptionHandler.handleException((RuntimeException) t,
+ AbstractConfiguredObject.this);
+ returnVal.set(null);
+ }
+ }
+ finally
+ {
+ if (!returnVal.isDone())
+ {
+ returnVal.setException(t);
+ }
+ }
+ }
+ }, getTaskExecutor().getExecutor());
}
catch(RuntimeException e)
{
@@ -825,51 +842,15 @@ public abstract class AbstractConfigured
}
}
}
- });
- counter.incrementCount();
- applyToChildren(new Action<ConfiguredObject<?>>()
- {
+
@Override
- public void performAction(final ConfiguredObject<?> child)
+ public void onFailure(final Throwable t)
{
- if (child instanceof AbstractConfiguredObject)
- {
- final AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child;
- if (configuredObject._dynamicState.get() == DynamicState.OPENED)
- {
- counter.incrementCount();
- Futures.addCallback(configuredObject.doAttainState(exceptionHandler),
- new FutureCallback()
- {
- @Override
- public void onSuccess(final Object result)
- {
- counter.decrementCount();
- }
-
- @Override
- public void onFailure(final Throwable t)
- {
- try
- {
- if (t instanceof RuntimeException)
- {
- exceptionHandler.handleException((RuntimeException) t,
- configuredObject);
- }
- }
- finally
- {
- counter.decrementCount();
- }
- }
- },getTaskExecutor().getExecutor());
-
- }
- }
+ // One or more children failed to attain state but the error could not be handled by the handler
+ returnVal.setException(t);
}
});
- counter.decrementCount();
+
return returnVal;
}
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java?rev=1694857&r1=1694856&r2=1694857&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/AbstractConfiguredObjectTest.java Sun Aug 9 08:13:07 2015
@@ -19,10 +19,14 @@
package org.apache.qpid.server.model.testmodels.hierarchy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.ExecutionException;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
@@ -31,6 +35,8 @@ import org.apache.qpid.server.configurat
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.SystemConfig;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.test.utils.QpidTestCase;
@@ -102,18 +108,11 @@ public class AbstractConfiguredObjectTes
public void testGetChildren_NewChild()
{
- final String carName = "myCar";
- Map<String, Object> carAttributes = new HashMap<>();
- carAttributes.put(ConfiguredObject.NAME, carName);
- carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
-
- TestCar car = _model.getObjectFactory().create(TestCar.class, carAttributes);
-
+ TestCar car = _model.getObjectFactory().create(TestCar.class, Collections.<String, Object>singletonMap(ConfiguredObject.NAME, "myCar"));
String engineName = "myEngine";
Map<String, Object> engineAttributes = new HashMap<>();
engineAttributes.put(ConfiguredObject.NAME, engineName);
- engineAttributes.put(ConfiguredObject.TYPE, TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE);
TestEngine engine = (TestEngine) car.createChild(TestEngine.class, engineAttributes);
@@ -130,51 +129,12 @@ public class AbstractConfiguredObjectTes
public void testGetChildren_RecoveredChild() throws Exception
{
- final String carName = "myCar";
- Map<String, Object> carAttributes = new HashMap<>();
- carAttributes.put(ConfiguredObject.NAME, carName);
- carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
-
- final TestCar car = _model.getObjectFactory().create(TestCar.class, carAttributes);
-
- String engineName = "myEngine";
- final Map<String, Object> engineAttributes = new HashMap<>();
- engineAttributes.put(ConfiguredObject.NAME, engineName);
- engineAttributes.put(ConfiguredObject.TYPE, TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE);
-
- ConfiguredObjectRecord engineCor = new ConfiguredObjectRecord()
- {
- @Override
- public UUID getId()
- {
- return UUID.randomUUID();
- }
-
- @Override
- public String getType()
- {
- return TestEngine.class.getSimpleName();
- }
-
- @Override
- public Map<String, Object> getAttributes()
- {
- return engineAttributes;
- }
-
- @Override
- public Map<String, UUID> getParents()
- {
- return Collections.singletonMap(TestCar.class.getSimpleName(), car.getId());
- }
- };
-
- // Recover and resolve the child. Resolving the child registers the child with its parent (car),
- // but the child is not open, so won't have attained state
- TestEngine engine = (TestEngine) _model.getObjectFactory().recover(engineCor, car).resolve();
+ final TestCar car = recoverParentAndChild();
// Check we can observe the recovered child from the parent
assertEquals(1, car.getChildren(TestEngine.class).size());
+ TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
+
assertEquals(engine, car.getChildById(TestEngine.class, engine.getId()));
assertEquals(engine, car.getChildByName(TestEngine.class, engine.getName()));
@@ -182,30 +142,156 @@ public class AbstractConfiguredObjectTes
assertNotNull(attainedChild);
assertFalse("Engine should not have yet attained state", attainedChild.isDone());
- engine.open();
+ car.open();
assertTrue("Engine should have now attained state", attainedChild.isDone());
assertEquals(engine, attainedChild.get());
}
- public void testCloseAwaitsChildCloseCompletion()
+ public void testOpenAwaitsChildToAttainState() throws Exception
{
- final String carName = "myCar";
- Map<String, Object> carAttributes = new HashMap<>();
- carAttributes.put(ConfiguredObject.NAME, carName);
- carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
+ SettableFuture<Void> engineStateChangeControllingFuture = SettableFuture.create();
- TestCar car = _model.getObjectFactory().create(TestCar.class, carAttributes);
+ final TestCar car = recoverParentAndChild();
+
+ // Check we can observe the recovered child from the parent
+ assertEquals(1, car.getChildren(TestEngine.class).size());
+ TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
+ engine.setStateChangeFuture(engineStateChangeControllingFuture);
+
+ ListenableFuture carFuture = car.openAsync();
+ assertFalse("car open future has completed before engine has attained state", carFuture.isDone());
+
+ engineStateChangeControllingFuture.set(null);
+
+ assertTrue("car open future has not completed", carFuture.isDone());
+ carFuture.get();
+ }
+
+ public void testOpenAwaitsChildToAttainState_ChildStateChangeAsyncErrors() throws Exception
+ {
+ SettableFuture<Void> engineStateChangeControllingFuture = SettableFuture.create();
+
+ final TestCar car = recoverParentAndChild();
+
+ // Check we can observe the recovered child from the parent
+ assertEquals(1, car.getChildren(TestEngine.class).size());
+ TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
+ engine.setStateChangeFuture(engineStateChangeControllingFuture);
+
+ ListenableFuture carFuture = car.openAsync();
+ assertFalse("car open future has completed before engine has attained state", carFuture.isDone());
+
+ engineStateChangeControllingFuture.setException(new RuntimeException("child attain state exception"));
+
+ assertTrue("car open future has not completed", carFuture.isDone());
+ carFuture.get();
+
+ assertEquals(State.ERRORED, engine.getState());
+ }
+
+ public void testOpenAwaitsChildToAttainState_ChildStateChangeSyncErrors() throws Exception
+ {
+ final TestCar car = recoverParentAndChild();
+
+ // Check we can observe the recovered child from the parent
+ assertEquals(1, car.getChildren(TestEngine.class).size());
+ TestEngine engine = (TestEngine) car.getChildren(TestEngine.class).iterator().next();
+
+ engine.setStateChangeException(new RuntimeException("child attain state exception"));
+
+ ListenableFuture carFuture = car.openAsync();
+
+ assertTrue("car open future has not completed", carFuture.isDone());
+ carFuture.get();
+
+ assertEquals(State.ERRORED, engine.getState());
+ }
+
+ public void testCreateAwaitsAttainState()
+ {
+ SettableFuture stateChangeFuture = SettableFuture.create();
+
+ TestCar car = _model.getObjectFactory().create(TestCar.class, Collections.<String, Object>singletonMap(ConfiguredObject.NAME, "myCar"));
+
+ Map<String, Object> engineAttributes = new HashMap<>();
+ engineAttributes.put(ConfiguredObject.NAME, "myEngine");
+ engineAttributes.put(TestEngine.STATE_CHANGE_FUTURE, stateChangeFuture);
+
+ ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+ assertFalse("create child has completed before state change completes", engine.isDone());
+
+ stateChangeFuture.set(null);
+
+ assertTrue("create child has not completed", engine.isDone());
+ }
+
+ public void testCreateAwaitsAttainState_StateChangeAsyncErrors() throws Exception
+ {
+ SettableFuture stateChangeFuture = SettableFuture.create();
+ RuntimeException stateChangeException = new RuntimeException("state change error");
+
+ TestCar car = _model.getObjectFactory().create(TestCar.class, Collections.<String, Object>singletonMap(ConfiguredObject.NAME, "myCar"));
+ Map<String, Object> engineAttributes = new HashMap<>();
+ engineAttributes.put(ConfiguredObject.NAME, "myEngine");
+ engineAttributes.put(TestEngine.STATE_CHANGE_FUTURE, stateChangeFuture);
+
+ ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+ assertFalse("create child has completed before state change completes", engine.isDone());
+
+ stateChangeFuture.setException(stateChangeException);
+
+ assertTrue("create child has not completed", engine.isDone());
+ try
+ {
+ engine.get();
+ fail("Exception not thrown");
+ }
+ catch (ExecutionException ee)
+ {
+ assertSame(stateChangeException, ee.getCause());
+ }
+ }
+
+ public void testCreateAwaitsAttainState_StateChangeSyncErrors() throws Exception
+ {
+ RuntimeException stateChangeException = new RuntimeException("state change error");
+
+ TestCar car = _model.getObjectFactory().create(TestCar.class, Collections.<String, Object>singletonMap(ConfiguredObject.NAME, "myCar"));
+
+ Map<String, Object> engineAttributes = new HashMap<>();
+ engineAttributes.put(ConfiguredObject.NAME, "myEngine");
+ engineAttributes.put(TestEngine.STATE_CHANGE_EXCEPTION, stateChangeException);
+
+ ListenableFuture engine = car.createChildAsync(TestEngine.class, engineAttributes);
+ assertTrue("create child has not completed", engine.isDone());
+
+ try
+ {
+ engine.get();
+ fail("Exception not thrown");
+ }
+ catch (ExecutionException ee)
+ {
+ assertSame(stateChangeException, ee.getCause());
+ }
+ }
+
+ public void testCloseAwaitsChildCloseCompletion()
+ {
SettableFuture<Void> engineCloseControllingFuture = SettableFuture.create();
+ TestCar car = _model.getObjectFactory().create(TestCar.class,
+ Collections.<String, Object>singletonMap(ConfiguredObject.NAME,
+ "myCar"));
+
String engineName = "myEngine";
Map<String, Object> engineAttributes = new HashMap<>();
engineAttributes.put(ConfiguredObject.NAME, engineName);
- engineAttributes.put(ConfiguredObject.TYPE, TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE);
+ engineAttributes.put(TestEngine.BEFORE_CLOSE_FUTURE, engineCloseControllingFuture);
TestEngine engine = (TestEngine) car.createChild(TestEngine.class, engineAttributes);
- engine.setBeforeCloseFuture(engineCloseControllingFuture);
ListenableFuture carListenableFuture = car.closeAsync();
assertFalse("car close future has completed before engine closed", carListenableFuture.isDone());
@@ -318,5 +404,82 @@ public class AbstractConfiguredObjectTes
assertSame(engine, car.getChildByName(TestEngine.class, engine.getName()));
}
+ /** Simulates recovery of a parent/child from a store. Neither will be open yet. */
+ private TestCar recoverParentAndChild()
+ {
+ final SystemConfig mockSystemConfig = mock(SystemConfig.class);
+ when(mockSystemConfig.getId()).thenReturn(UUID.randomUUID());
+ when(mockSystemConfig.getModel()).thenReturn(TestModel.getInstance());
+
+ final String carName = "myCar";
+ final Map<String, Object> carAttributes = new HashMap<>();
+ carAttributes.put(ConfiguredObject.NAME, carName);
+ carAttributes.put(ConfiguredObject.TYPE, TestKitCarImpl.TEST_KITCAR_TYPE);
+
+ ConfiguredObjectRecord carCor = new ConfiguredObjectRecord()
+ {
+ @Override
+ public UUID getId()
+ {
+ return UUID.randomUUID();
+ }
+
+ @Override
+ public String getType()
+ {
+ return TestCar.class.getSimpleName();
+ }
+
+ @Override
+ public Map<String, Object> getAttributes()
+ {
+ return carAttributes;
+ }
+
+ @Override
+ public Map<String, UUID> getParents()
+ {
+ return Collections.singletonMap(SystemConfig.class.getSimpleName(), mockSystemConfig.getId());
+ }
+ };
+
+ final TestCar car = (TestCar) _model.getObjectFactory().recover(carCor, mockSystemConfig).resolve();
+
+ String engineName = "myEngine";
+ final Map<String, Object> engineAttributes = new HashMap<>();
+ engineAttributes.put(ConfiguredObject.NAME, engineName);
+ engineAttributes.put(ConfiguredObject.TYPE, TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE);
+
+ ConfiguredObjectRecord engineCor = new ConfiguredObjectRecord()
+ {
+ @Override
+ public UUID getId()
+ {
+ return UUID.randomUUID();
+ }
+
+ @Override
+ public String getType()
+ {
+ return TestEngine.class.getSimpleName();
+ }
+
+ @Override
+ public Map<String, Object> getAttributes()
+ {
+ return engineAttributes;
+ }
+
+ @Override
+ public Map<String, UUID> getParents()
+ {
+ return Collections.singletonMap(TestCar.class.getSimpleName(), car.getId());
+ }
+ };
+
+ _model.getObjectFactory().recover(engineCor, car).resolve();
+ return car;
+ }
+
}
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java?rev=1694857&r1=1694856&r2=1694857&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestAbstractEngineImpl.java Sun Aug 9 08:13:07 2015
@@ -28,11 +28,21 @@ import com.google.common.util.concurrent
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ManagedAttributeField;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.StateTransition;
public class TestAbstractEngineImpl<X extends TestAbstractEngineImpl<X>> extends AbstractConfiguredObject<X> implements TestEngine<X>
{
+ @ManagedAttributeField
private ListenableFuture<Void> _beforeCloseFuture = Futures.immediateFuture(null);
+ @ManagedAttributeField
+ private Object _stateChangeFuture = Futures.immediateFuture(null);
+
+ @ManagedAttributeField
+ private RuntimeException _stateChangeException;
+
public TestAbstractEngineImpl(final Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> parents,
final Map<String, Object> attributes)
{
@@ -40,14 +50,56 @@ public class TestAbstractEngineImpl<X ex
}
@Override
- public void setBeforeCloseFuture(final ListenableFuture listenableFuture)
+ public Object getBeforeCloseFuture()
+ {
+ return _beforeCloseFuture;
+ }
+
+ @Override
+ public void setBeforeCloseFuture(final ListenableFuture<Void> listenableFuture)
{
_beforeCloseFuture = listenableFuture;
}
@Override
+ public Object getStateChangeFuture()
+ {
+ return _stateChangeFuture;
+ }
+
+ @Override
+ public void setStateChangeFuture(final ListenableFuture<Void> listenableFuture)
+ {
+ _stateChangeFuture = listenableFuture;
+ }
+
+
+ @Override
+ public Object getStateChangeException()
+ {
+ return _stateChangeException;
+ }
+
+ @Override
+ public void setStateChangeException(final RuntimeException exception)
+ {
+ _stateChangeException = exception;
+ }
+
+ @Override
protected ListenableFuture<Void> beforeClose()
{
return _beforeCloseFuture;
}
+
+ @StateTransition(currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE)
+ private ListenableFuture<Void> onActivate()
+ {
+ RuntimeException stateChangeException = _stateChangeException;
+ if (stateChangeException != null)
+ {
+ throw stateChangeException;
+ }
+ return (ListenableFuture<Void>) _stateChangeFuture;
+ }
}
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java?rev=1694857&r1=1694856&r2=1694857&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestEngine.java Sun Aug 9 08:13:07 2015
@@ -21,13 +21,36 @@
package org.apache.qpid.server.model.testmodels.hierarchy;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ManagedAttribute;
import org.apache.qpid.server.model.ManagedObject;
-@ManagedObject(category = true)
+@ManagedObject(category = true, defaultType = TestElecEngineImpl.TEST_ELEC_ENGINE_TYPE)
public interface TestEngine<X extends TestEngine<X>> extends ConfiguredObject<X>
{
- /** Injectable close future, used to control when/how close occurs during test */
- void setBeforeCloseFuture(ListenableFuture listenableFuture);
+ String BEFORE_CLOSE_FUTURE = "beforeCloseFuture";
+ String STATE_CHANGE_FUTURE = "stateChangeFuture";
+ String STATE_CHANGE_EXCEPTION = "stateChangeException";
+
+ /* Injectable close future, used to control when/how close completes during the test */
+ @ManagedAttribute
+ Object getBeforeCloseFuture();
+
+ void setBeforeCloseFuture(ListenableFuture<Void> listenableFuture);
+
+ /* Injectable state change future, used to control when/how asynch state transition completes during the test */
+
+ @ManagedAttribute
+ Object getStateChangeFuture();
+
+ void setStateChangeFuture(ListenableFuture<Void> listenableFuture);
+
+ /* Injectable exception, used to introduce an exception into a state change transition */
+
+ @ManagedAttribute
+ Object getStateChangeException();
+ void setStateChangeException(RuntimeException exception);
+
}
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestKitCarImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestKitCarImpl.java?rev=1694857&r1=1694856&r2=1694857&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestKitCarImpl.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestKitCarImpl.java Sun Aug 9 08:13:07 2015
@@ -20,6 +20,8 @@ package org.apache.qpid.server.model.tes
import java.util.Map;
+import com.google.common.util.concurrent.ListenableFuture;
+
import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObject;
@@ -51,11 +53,11 @@ public class TestKitCarImpl extends Abst
}
@Override
- public <C extends ConfiguredObject> C createChild(final Class<C> childClass,
- final Map<String, Object> attributes,
- final ConfiguredObject... otherParents)
+ protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
+ final Map<String, Object> attributes,
+ final ConfiguredObject... otherParents)
{
- return (C) getObjectFactory().create(childClass, attributes, this);
+ return getObjectFactory().createAsync(childClass, attributes, this);
}
private static CurrentThreadTaskExecutor newTaskExecutor()
Modified: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestStandardCarImpl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestStandardCarImpl.java?rev=1694857&r1=1694856&r2=1694857&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestStandardCarImpl.java (original)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/model/testmodels/hierarchy/TestStandardCarImpl.java Sun Aug 9 08:13:07 2015
@@ -25,8 +25,11 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import com.google.common.util.concurrent.ListenableFuture;
+
import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
import org.apache.qpid.server.model.AbstractConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.ManagedObject;
import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
import org.apache.qpid.server.model.testmodels.TestSecurityManager;
@@ -55,6 +58,14 @@ public class TestStandardCarImpl extends
return currentThreadTaskExecutor;
}
+ @Override
+ protected <C extends ConfiguredObject> ListenableFuture<C> addChildAsync(final Class<C> childClass,
+ final Map<String, Object> attributes,
+ final ConfiguredObject... otherParents)
+ {
+ return getObjectFactory().createAsync(childClass, attributes, this);
+ }
+
@SuppressWarnings("unused")
public static Map<String, Collection<String>> getSupportedChildTypes()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org