diff --git a/community/bolt/src/main/java/org/neo4j/bolt/BoltKernelExtension.java b/community/bolt/src/main/java/org/neo4j/bolt/BoltKernelExtension.java index 73e3e31305fd..7af8ac7d6074 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/BoltKernelExtension.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/BoltKernelExtension.java @@ -47,12 +47,12 @@ import org.neo4j.bolt.v1.runtime.BoltFactoryImpl; import org.neo4j.configuration.Description; import org.neo4j.configuration.LoadableConfig; -import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.config.Setting; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.helpers.ListenSocketAddress; import org.neo4j.helpers.Service; import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.AvailabilityGuard; import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.api.security.AuthManager; import org.neo4j.kernel.api.security.UserManagerSupplier; @@ -61,7 +61,6 @@ import org.neo4j.kernel.configuration.ConnectorPortRegister; import org.neo4j.kernel.configuration.ssl.SslPolicyLoader; import org.neo4j.kernel.extension.KernelExtensionFactory; -import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.logging.LogService; import org.neo4j.kernel.impl.spi.KernelContext; import org.neo4j.kernel.internal.GraphDatabaseAPI; @@ -96,7 +95,7 @@ public interface Dependencies Config config(); - GraphDatabaseService db(); + GraphDatabaseAPI db(); JobScheduler scheduler(); @@ -104,7 +103,7 @@ public interface Dependencies Monitors monitors(); - ThreadToStatementContextBridge txBridge(); + AvailabilityGuard availabilityGuard(); BoltConnectionTracker sessionTracker(); @@ -130,8 +129,6 @@ public BoltKernelExtension() public Lifecycle newInstance( KernelContext context, Dependencies dependencies ) { Config config = dependencies.config(); - GraphDatabaseService gdb = dependencies.db(); - GraphDatabaseAPI api = (GraphDatabaseAPI) gdb; LogService logService = dependencies.logService(); Clock clock = dependencies.clock(); SslPolicyLoader sslPolicyFactory = dependencies.sslPolicyFactory(); @@ -150,8 +147,8 @@ public Lifecycle newInstance( KernelContext context, Dependencies dependencies ) TransportThrottleGroup throttleGroup = new TransportThrottleGroup( config, clock ); - BoltFactory boltFactory = life.add( new BoltFactoryImpl( api, dependencies.usageData(), - logService, dependencies.txBridge(), authentication, dependencies.sessionTracker(), config ) ); + BoltFactory boltFactory = new BoltFactoryImpl( dependencies.db(), dependencies.usageData(), dependencies.availabilityGuard(), + authentication, dependencies.sessionTracker(), config, logService ); BoltSchedulerProvider boltSchedulerProvider = life.add( new ExecutorBoltSchedulerProvider( config, new CachedThreadPoolExecutorFactory( log ), scheduler, logService ) ); BoltConnectionFactory boltConnectionFactory = diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/BoltFactoryImpl.java b/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/BoltFactoryImpl.java index a685e7da7714..5e097f7077e6 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/BoltFactoryImpl.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/BoltFactoryImpl.java @@ -24,63 +24,36 @@ import org.neo4j.bolt.BoltChannel; import org.neo4j.bolt.security.auth.Authentication; -import org.neo4j.graphdb.DependencyResolver; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.kernel.AvailabilityGuard; -import org.neo4j.kernel.GraphDatabaseQueryService; import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.logging.LogService; -import org.neo4j.kernel.impl.query.QueryExecutionEngine; import org.neo4j.kernel.internal.GraphDatabaseAPI; -import org.neo4j.kernel.lifecycle.LifecycleAdapter; import org.neo4j.udc.UsageData; -public class BoltFactoryImpl extends LifecycleAdapter implements BoltFactory +public class BoltFactoryImpl implements BoltFactory { - private final GraphDatabaseAPI gds; + private final GraphDatabaseAPI db; private final UsageData usageData; + private final AvailabilityGuard availabilityGuard; private final LogService logging; private final Authentication authentication; private final BoltConnectionTracker connectionTracker; - private final ThreadToStatementContextBridge txBridge; private final Config config; - private QueryExecutionEngine queryExecutionEngine; - private GraphDatabaseQueryService queryService; - private AvailabilityGuard availabilityGuard; - - public BoltFactoryImpl( GraphDatabaseAPI gds, UsageData usageData, LogService logging, - ThreadToStatementContextBridge txBridge, Authentication authentication, - BoltConnectionTracker connectionTracker, Config config ) + public BoltFactoryImpl( GraphDatabaseAPI db, UsageData usageData, AvailabilityGuard availabilityGuard, + Authentication authentication, BoltConnectionTracker connectionTracker, Config config, LogService logging ) { - this.gds = gds; + this.db = db; this.usageData = usageData; + this.availabilityGuard = availabilityGuard; this.logging = logging; - this.txBridge = txBridge; this.authentication = authentication; this.connectionTracker = connectionTracker; this.config = config; } - @Override - public void start() - { - DependencyResolver dependencyResolver = gds.getDependencyResolver(); - queryExecutionEngine = dependencyResolver.resolveDependency( QueryExecutionEngine.class ); - queryService = dependencyResolver.resolveDependency( GraphDatabaseQueryService.class ); - availabilityGuard = dependencyResolver.resolveDependency( AvailabilityGuard.class ); - } - - @Override - public void stop() - { - queryExecutionEngine = null; - queryService = null; - availabilityGuard = null; - } - @Override public BoltStateMachine newMachine( BoltChannel boltChannel, Clock clock ) { @@ -95,7 +68,6 @@ private TransactionStateMachine.SPI createTxSpi( Clock clock ) long bookmarkReadyTimeout = config.get( GraphDatabaseSettings.bookmark_ready_timeout ).toMillis(); Duration txAwaitDuration = Duration.ofMillis( bookmarkReadyTimeout ); - return new TransactionStateMachineSPI( gds, txBridge, queryExecutionEngine, - availabilityGuard, queryService, txAwaitDuration, clock ); + return new TransactionStateMachineSPI( db, availabilityGuard, txAwaitDuration, clock ); } } diff --git a/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPI.java b/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPI.java index 517ac85a22f9..960289804127 100644 --- a/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPI.java +++ b/community/bolt/src/main/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPI.java @@ -28,11 +28,11 @@ import org.neo4j.cypher.internal.javacompat.QueryResultProvider; import org.neo4j.graphdb.Result; import org.neo4j.internal.kernel.api.exceptions.KernelException; +import org.neo4j.internal.kernel.api.exceptions.TransactionFailureException; import org.neo4j.internal.kernel.api.security.LoginContext; import org.neo4j.kernel.AvailabilityGuard; import org.neo4j.kernel.GraphDatabaseQueryService; import org.neo4j.kernel.api.KernelTransaction; -import org.neo4j.internal.kernel.api.exceptions.TransactionFailureException; import org.neo4j.kernel.api.txtracking.TransactionIdTracker; import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.coreapi.InternalTransaction; @@ -53,33 +53,23 @@ class TransactionStateMachineSPI implements TransactionStateMachine.SPI { + private static final PropertyContainerLocker locker = new PropertyContainerLocker(); + private final GraphDatabaseAPI db; private final ThreadToStatementContextBridge txBridge; private final QueryExecutionEngine queryExecutionEngine; private final TransactionIdTracker transactionIdTracker; - private static final PropertyContainerLocker locker = new PropertyContainerLocker(); private final TransactionalContextFactory contextFactory; - private final GraphDatabaseQueryService queryService; private final Duration txAwaitDuration; private final Clock clock; - TransactionStateMachineSPI( GraphDatabaseAPI db, - ThreadToStatementContextBridge txBridge, - QueryExecutionEngine queryExecutionEngine, - AvailabilityGuard availabilityGuard, - GraphDatabaseQueryService queryService, - Duration txAwaitDuration, - Clock clock ) + TransactionStateMachineSPI( GraphDatabaseAPI db, AvailabilityGuard availabilityGuard, Duration txAwaitDuration, Clock clock ) { this.db = db; - this.txBridge = txBridge; - this.queryExecutionEngine = queryExecutionEngine; - - Supplier transactionIdStoreSupplier = db.getDependencyResolver().provideDependency( TransactionIdStore.class ); - this.transactionIdTracker = new TransactionIdTracker( transactionIdStoreSupplier, availabilityGuard ); - - this.contextFactory = Neo4jTransactionalContextFactory.create( queryService, locker ); - this.queryService = queryService; + this.txBridge = db.getDependencyResolver().resolveDependency( ThreadToStatementContextBridge.class ); + this.queryExecutionEngine = db.getDependencyResolver().resolveDependency( QueryExecutionEngine.class ); + this.transactionIdTracker = newTransactionIdTracker( db, availabilityGuard ); + this.contextFactory = newTransactionalContextFactory( db ); this.txAwaitDuration = txAwaitDuration; this.clock = clock; } @@ -125,7 +115,7 @@ public boolean isPeriodicCommit( String query ) public BoltResultHandle executeQuery( BoltQuerySource querySource, LoginContext loginContext, String statement, MapValue params ) { - InternalTransaction internalTransaction = queryService.beginTransaction( implicit, loginContext ); + InternalTransaction internalTransaction = db.beginTransaction( implicit, loginContext ); ClientConnectionInfo sourceDetails = new BoltConnectionInfo( querySource.principalName, querySource.clientName, querySource.connectionDescriptor.clientAddress(), @@ -178,4 +168,16 @@ public void terminate() }; } + + private static TransactionIdTracker newTransactionIdTracker( GraphDatabaseAPI db, AvailabilityGuard guard ) + { + Supplier transactionIdStoreSupplier = db.getDependencyResolver().provideDependency( TransactionIdStore.class ); + return new TransactionIdTracker( transactionIdStoreSupplier, guard ); + } + + private static TransactionalContextFactory newTransactionalContextFactory( GraphDatabaseAPI db ) + { + GraphDatabaseQueryService queryService = db.getDependencyResolver().resolveDependency( GraphDatabaseQueryService.class ); + return Neo4jTransactionalContextFactory.create( queryService, locker ); + } } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/BoltFactoryImplTest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/BoltFactoryImplTest.java index b5a8def6b72b..9d1db6b92e05 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/BoltFactoryImplTest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/BoltFactoryImplTest.java @@ -30,88 +30,29 @@ import org.neo4j.kernel.GraphDatabaseQueryService; import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.logging.NullLogService; -import org.neo4j.kernel.impl.transaction.log.TransactionIdStore; import org.neo4j.kernel.internal.GraphDatabaseAPI; +import org.neo4j.logging.NullLog; import org.neo4j.test.OnDemandJobScheduler; import org.neo4j.udc.UsageData; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class BoltFactoryImplTest { private static final Clock CLOCK = Clock.systemUTC(); - private static final BoltChannel boltChannel = mock( BoltChannel.class ); + private static final BoltChannel CHANNEL = mock( BoltChannel.class ); @Test - public void newMachineThrowsWhenNotStarted() + public void shouldCreateBoltStateMachines() { - BoltFactoryImpl boltFactory = newBoltFactory(); + BoltFactoryImpl factory = newBoltFactory(); - try - { - boltFactory.newMachine( boltChannel, CLOCK ); - fail( "Exception expected" ); - } - catch ( Exception e ) - { - // expected - } - } - - @Test - public void newMachineThrowsWhenStopped() - { - BoltFactoryImpl boltFactory = newBoltFactory(); - - boltFactory.start(); - - BoltStateMachine stateMachine = boltFactory.newMachine( boltChannel, CLOCK ); - - assertNotNull( stateMachine ); - - boltFactory.stop(); - - try - { - boltFactory.newMachine( boltChannel, CLOCK ); - fail( "Exception expected" ); - } - catch ( Exception e ) - { - // expected - } - } - - @Test - public void txIdStoreRefreshedAfterRestart() - { - GraphDatabaseAPI db = newDbMock(); - DependencyResolver dependencyResolver = db.getDependencyResolver(); - TransactionIdStore txIdStoreBeforeRestart = mock( TransactionIdStore.class ); - when( txIdStoreBeforeRestart.getLastClosedTransactionId() ).thenReturn( 42L ); - TransactionIdStore txIdStoreAfterRestart = mock( TransactionIdStore.class ); - when( txIdStoreAfterRestart.getLastClosedTransactionId() ).thenReturn( 4242L ); - when( dependencyResolver.provideDependency( TransactionIdStore.class ) ) - .thenReturn( () -> txIdStoreBeforeRestart ).thenReturn( () -> txIdStoreAfterRestart ); - - BoltFactoryImpl boltFactory = newBoltFactory( db ); - - boltFactory.start(); - - BoltStateMachine stateMachine1 = boltFactory.newMachine( boltChannel, CLOCK ); - assertEquals( 42, stateMachine1.spi.transactionSpi().newestEncounteredTxId() ); - - boltFactory.stop(); - boltFactory.start(); + BoltStateMachine boltStateMachine = factory.newMachine( CHANNEL, CLOCK ); - BoltStateMachine stateMachine2 = boltFactory.newMachine( boltChannel, CLOCK ); - assertEquals( 4242, stateMachine2.spi.transactionSpi().newestEncounteredTxId() ); + assertNotNull( boltStateMachine ); } private static BoltFactoryImpl newBoltFactory() @@ -121,9 +62,8 @@ private static BoltFactoryImpl newBoltFactory() private static BoltFactoryImpl newBoltFactory( GraphDatabaseAPI db ) { - return new BoltFactoryImpl( db, new UsageData( new OnDemandJobScheduler() ), NullLogService.getInstance(), - new ThreadToStatementContextBridge( mock( AvailabilityGuard.class ) ), mock( Authentication.class ), BoltConnectionTracker.NOOP, - Config.defaults() ); + return new BoltFactoryImpl( db, new UsageData( new OnDemandJobScheduler() ), new AvailabilityGuard( CLOCK, NullLog.getInstance() ), + mock( Authentication.class ), BoltConnectionTracker.NOOP, Config.defaults(), NullLogService.getInstance() ); } private static GraphDatabaseAPI newDbMock() diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPITest.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPITest.java index e9a32ae5c4a7..6a3b29e3ca0c 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPITest.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/TransactionStateMachineSPITest.java @@ -124,17 +124,21 @@ private static TransactionStateMachineSPI createTxSpi( Supplier txIdStore, Duration txAwaitDuration, AvailabilityGuard availabilityGuard, Clock clock ) { - GraphDatabaseQueryService queryService = mock( GraphDatabaseQueryService.class ); + QueryExecutionEngine queryExecutionEngine = mock( QueryExecutionEngine.class ); + DependencyResolver dependencyResolver = mock( DependencyResolver.class ); - GraphDatabaseAPI db = mock( GraphDatabaseAPI.class ); + ThreadToStatementContextBridge bridge = new ThreadToStatementContextBridge( availabilityGuard ); + when( dependencyResolver.resolveDependency( ThreadToStatementContextBridge.class ) ).thenReturn( bridge ); + when( dependencyResolver.resolveDependency( QueryExecutionEngine.class ) ).thenReturn( queryExecutionEngine ); + when( dependencyResolver.provideDependency( TransactionIdStore.class ) ).thenReturn( txIdStore ); - when( queryService.getDependencyResolver() ).thenReturn( dependencyResolver ); + GraphDatabaseAPI db = mock( GraphDatabaseAPI.class ); when( db.getDependencyResolver() ).thenReturn( dependencyResolver ); - when(dependencyResolver.provideDependency( TransactionIdStore.class )).thenReturn( txIdStore ); + GraphDatabaseQueryService queryService = mock( GraphDatabaseQueryService.class ); + when( queryService.getDependencyResolver() ).thenReturn( dependencyResolver ); + when( dependencyResolver.resolveDependency( GraphDatabaseQueryService.class ) ).thenReturn( queryService ); - return new TransactionStateMachineSPI( db, new ThreadToStatementContextBridge( mock( AvailabilityGuard.class ) ), - mock( QueryExecutionEngine.class ), availabilityGuard, queryService, txAwaitDuration, - clock ); + return new TransactionStateMachineSPI( db, availabilityGuard, txAwaitDuration, clock ); } } diff --git a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/SessionRule.java b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/SessionRule.java index a5373dd78530..0f907575fac3 100644 --- a/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/SessionRule.java +++ b/community/bolt/src/test/java/org/neo4j/bolt/v1/runtime/integration/SessionRule.java @@ -40,11 +40,11 @@ import org.neo4j.graphdb.DependencyResolver; import org.neo4j.graphdb.config.Setting; import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.AvailabilityGuard; import org.neo4j.kernel.api.bolt.BoltConnectionTracker; import org.neo4j.kernel.api.security.AuthManager; import org.neo4j.kernel.api.security.UserManagerSupplier; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.core.ThreadToStatementContextBridge; import org.neo4j.kernel.impl.logging.NullLogService; import org.neo4j.kernel.impl.transaction.log.TransactionIdStore; import org.neo4j.kernel.internal.GraphDatabaseAPI; @@ -75,13 +75,12 @@ public void evaluate() throws Throwable boltFactory = new BoltFactoryImpl( gdb, new UsageData( null ), - NullLogService.getInstance(), - resolver.resolveDependency( ThreadToStatementContextBridge.class ), + resolver.resolveDependency( AvailabilityGuard.class ), authentication, BoltConnectionTracker.NOOP, - Config.defaults() + Config.defaults(), + NullLogService.getInstance() ); - boltFactory.start(); try { base.evaluate();