+ @Test(expected=TransactionCommitFailedException.class)
+ public void testRejectedCommit() throws Exception {
+
+ commitExecutor.delegate = Mockito.mock( ExecutorService.class );
+ Mockito.doThrow( new RejectedExecutionException( "mock" ) )
+ .when( commitExecutor.delegate ).execute( Mockito.any( Runnable.class ) );
+ Mockito.doNothing().when( commitExecutor.delegate ).shutdown();
+ Mockito.doReturn( Collections.emptyList() ).when( commitExecutor.delegate ).shutdownNow();
+ Mockito.doReturn( "" ).when( commitExecutor.delegate ).toString();
+ Mockito.doReturn( true ).when( commitExecutor.delegate )
+ .awaitTermination( Mockito.anyLong(), Mockito.any( TimeUnit.class ) );
+
+ DOMDataReadWriteTransaction writeTx = domBroker.newReadWriteTransaction();
+ writeTx.put( OPERATIONAL, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME) );
+
+ writeTx.submit().checkedGet( 5, TimeUnit.SECONDS );
+ }
+
+ /**
+ * Tests a simple DataChangeListener notification after a write.
+ */
+ @Test
+ public void testDataChangeListener() throws Throwable {
+
+ final NormalizedNode<?, ?> testNode = ImmutableNodes.containerNode( TestModel.TEST_QNAME );
+
+ TestDOMDataChangeListener dcListener = new TestDOMDataChangeListener();
+
+ domBroker.registerDataChangeListener( OPERATIONAL, TestModel.TEST_PATH,
+ dcListener, DataChangeScope.BASE );
+
+ final DOMDataWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
+ assertNotNull( writeTx );
+
+ writeTx.put( OPERATIONAL, TestModel.TEST_PATH, testNode );
+
+ AtomicReference<Throwable> caughtEx = submitTxAsync( writeTx );
+
+ dcListener.waitForChange();
+
+ if( caughtEx.get() != null ) {
+ throw caughtEx.get();
+ }
+
+ NormalizedNode<?, ?> actualNode = dcListener.change.getCreatedData().get( TestModel.TEST_PATH );
+ assertEquals( "Created node", testNode, actualNode );
+ }
+
+ /**
+ * Tests a DataChangeListener that does an async submit of a write Tx in its onDataChanged method.
+ * This should succeed without deadlock.
+ */
+ @Test
+ public void testDataChangeListenerDoingAsyncWriteTxSubmit() throws Throwable {
+
+ final AtomicReference<Throwable> caughtCommitEx = new AtomicReference<>();
+ final CountDownLatch commitCompletedLatch = new CountDownLatch( 1 );
+
+ TestDOMDataChangeListener dcListener = new TestDOMDataChangeListener() {
+ @Override
+ public void onDataChanged( AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change ) {
+
+ DOMDataWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
+ writeTx.put( OPERATIONAL, TestModel.TEST2_PATH,
+ ImmutableNodes.containerNode( TestModel.TEST2_QNAME ) );
+ Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() {
+ @Override
+ public void onSuccess( Void result ) {
+ commitCompletedLatch.countDown();
+ }
+
+ @Override
+ public void onFailure( Throwable t ) {
+ caughtCommitEx.set( t );
+ commitCompletedLatch.countDown();
+ }
+ } );
+
+ super.onDataChanged( change );
+ }
+ };
+
+ domBroker.registerDataChangeListener( OPERATIONAL, TestModel.TEST_PATH,
+ dcListener, DataChangeScope.BASE );
+
+ final DOMDataWriteTransaction writeTx = domBroker.newWriteOnlyTransaction();
+ assertNotNull( writeTx );