NetworkSession { private CompletionStage<Connection> acquireConnection( AccessMode mode ) { CompletionStage<Connection> currentConnectionStage = connectionStage; CompletionStage<Connection> newConnectionStage = resultCursorStage.thenCompose( cursor -> { if ( cursor == null ) { return completedWithNull(); } return cursor.pullAllFailureAsync(); } ).thenCompose( error -> { if ( error == null ) { return currentConnectionStage.exceptionally( ignore -> null ); } else { throw new CompletionException( error ); } } ).thenCompose( existingConnection -> { if ( existingConnection != null && existingConnection.isOpen() ) { throw new IllegalStateException( "Existing open connection detected" ); } return connectionProvider.acquireConnection( connectionContext.contextWithMode( mode ) ); } ); connectionStage = newConnectionStage.exceptionally( error -> null ); return newConnectionStage; } NetworkSession( ConnectionProvider connectionProvider, RetryLogic retryLogic, DatabaseName databaseName, AccessMode mode,
            BookmarkHolder bookmarkHolder, long fetchSize, Logging logging ); CompletionStage<ResultCursor> runAsync(Query query, TransactionConfig config, boolean waitForRunResponse ); CompletionStage<RxResultCursor> runRx(Query query, TransactionConfig config ); CompletionStage<UnmanagedTransaction> beginTransactionAsync( TransactionConfig config ); CompletionStage<UnmanagedTransaction> beginTransactionAsync( AccessMode mode, TransactionConfig config ); CompletionStage<Void> resetAsync(); RetryLogic retryLogic(); Bookmark lastBookmark(); CompletionStage<Void> releaseConnectionAsync(); CompletionStage<Connection> connectionAsync(); boolean isOpen(); CompletionStage<Void> closeAsync();  }
@Test void acquiresNewConnectionForRun() { run( session, "RETURN 1" ); verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); }
@Test void closeWithoutConnection() { NetworkSession session = newSession( connectionProvider ); close( session ); verify( connectionProvider, never() ).acquireConnection( any( ConnectionContext.class ) ); }
@Test void acquiresNewConnectionForBeginTx() { UnmanagedTransaction tx = beginTransaction( session ); assertNotNull( tx ); verify( connectionProvider ).acquireConnection( any( ConnectionContext.class ) ); }
@Test void shouldDoNothingWhenClosingWithoutAcquiredConnection() { RuntimeException error = new RuntimeException( "Hi" ); when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ).thenReturn( failedFuture( error ) ); Exception e = assertThrows( Exception.class, () -> run( session, "RETURN 1" ) ); assertEquals( error, e ); close( session ); }
@Test void shouldRunAfterRunFailureToAcquireConnection() { RuntimeException error = new RuntimeException( "Hi" ); when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) .thenReturn( failedFuture( error ) ).thenReturn( completedFuture( connection ) ); Exception e = assertThrows( Exception.class, () -> run( session,"RETURN 1" ) ); assertEquals( error, e ); run( session, "RETURN 2" ); verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); verifyRunAndPull( connection, "RETURN 2" ); }
@Test void shouldRunAfterBeginTxFailureOnBookmark() { RuntimeException error = new RuntimeException( "Hi" ); Connection connection1 = connectionMock( BoltProtocolV4.INSTANCE ); setupFailingBegin( connection1, error ); Connection connection2 = connectionMock( BoltProtocolV4.INSTANCE ); when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) .thenReturn( completedFuture( connection1 ) ).thenReturn( completedFuture( connection2 ) ); Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); NetworkSession session = newSession( connectionProvider, bookmark ); Exception e = assertThrows( Exception.class, () -> beginTransaction( session ) ); assertEquals( error, e ); run( session, "RETURN 2" ); verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); verifyBeginTx( connection1, bookmark ); verifyRunAndPull( connection2, "RETURN 2" ); }
@Test void shouldBeginTxAfterBeginTxFailureOnBookmark() { RuntimeException error = new RuntimeException( "Hi" ); Connection connection1 = connectionMock( BoltProtocolV4.INSTANCE ); setupFailingBegin( connection1, error ); Connection connection2 = connectionMock( BoltProtocolV4.INSTANCE ); when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) .thenReturn( completedFuture( connection1 ) ).thenReturn( completedFuture( connection2 ) ); Bookmark bookmark = InternalBookmark.parse( "neo4j:bookmark:v1:tx42" ); NetworkSession session = newSession( connectionProvider, bookmark ); Exception e = assertThrows( Exception.class, () -> beginTransaction( session ) ); assertEquals( error, e ); beginTransaction( session ); verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); verifyBeginTx( connection1, bookmark ); verifyBeginTx( connection2, bookmark ); }
@Test void shouldBeginTxAfterRunFailureToAcquireConnection() { RuntimeException error = new RuntimeException( "Hi" ); when( connectionProvider.acquireConnection( any( ConnectionContext.class ) ) ) .thenReturn( failedFuture( error ) ).thenReturn( completedFuture( connection ) ); Exception e = assertThrows( Exception.class, () -> run( session, "RETURN 1" ) ); assertEquals( error, e ); beginTransaction( session ); verify( connectionProvider, times( 2 ) ).acquireConnection( any( ConnectionContext.class ) ); verifyBeginTx( connection ); }