diff --git a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java index 69d106eae8a25..c01c070787cdc 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -1042,10 +1042,9 @@ private KernelModule buildKernel( IntegrityValidator integrityValidator, Transac UpdateableSchemaState updateableSchemaState, LabelScanStore labelScanStore, SchemaIndexProviderMap schemaIndexProviderMap, ProcedureCache procedureCache ) { - final TransactionCommitProcess transactionCommitProcess = - commitProcessFactory.create( appender, kernelHealth, neoStores, storeApplier, - new NeoStoreInjectedTransactionValidator( integrityValidator ), indexUpdatesValidator, - config ); + NeoStoreInjectedTransactionValidator validator = new NeoStoreInjectedTransactionValidator( integrityValidator ); + TransactionCommitProcess transactionCommitProcess = commitProcessFactory.create( appender, storeApplier, + validator, indexUpdatesValidator, config ); /* * This is used by legacy indexes and constraint indexes whenever a transaction is to be spawned diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/CommitProcessFactory.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/CommitProcessFactory.java index b279bfe96868c..ccc14efc876dd 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/api/CommitProcessFactory.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/api/CommitProcessFactory.java @@ -19,17 +19,14 @@ */ package org.neo4j.kernel.impl.api; -import org.neo4j.kernel.KernelHealth; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; -import org.neo4j.kernel.impl.store.NeoStores; import org.neo4j.kernel.impl.transaction.log.TransactionAppender; import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; public interface CommitProcessFactory { - TransactionCommitProcess create( TransactionAppender appender, KernelHealth kernelHealth, - NeoStores neoStores, TransactionRepresentationStoreApplier storeApplier, - NeoStoreInjectedTransactionValidator txValidator, - IndexUpdatesValidator indexUpdatesValidator, Config config ); + TransactionCommitProcess create( TransactionAppender appender, TransactionRepresentationStoreApplier storeApplier, + NeoStoreInjectedTransactionValidator txValidator, IndexUpdatesValidator indexUpdatesValidator, + Config config ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactory.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactory.java new file mode 100644 index 0000000000000..47c53fc6a214b --- /dev/null +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2002-2015 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.factory; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.api.CommitProcessFactory; +import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; +import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; +import org.neo4j.kernel.impl.transaction.log.TransactionAppender; +import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; + +public class CommunityCommitProcessFactory implements CommitProcessFactory +{ + @Override + public TransactionCommitProcess create( TransactionAppender appender, + TransactionRepresentationStoreApplier storeApplier, NeoStoreInjectedTransactionValidator txValidator, + IndexUpdatesValidator indexUpdatesValidator, Config config ) + { + if ( config.get( GraphDatabaseSettings.read_only ) ) + { + return new ReadOnlyTransactionCommitProcess(); + } + return new TransactionRepresentationCommitProcess( appender, storeApplier, indexUpdatesValidator ); + } +} diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java index e834c7ca18d39..d332539d19ba2 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/factory/CommunityEditionModule.java @@ -31,18 +31,11 @@ import org.neo4j.kernel.GraphDatabaseAPI; import org.neo4j.kernel.IdGeneratorFactory; import org.neo4j.kernel.KernelData; -import org.neo4j.kernel.KernelHealth; import org.neo4j.kernel.NeoStoreDataSource; import org.neo4j.kernel.Version; import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException; import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.impl.api.CommitProcessFactory; -import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; import org.neo4j.kernel.impl.api.SchemaWriteGuard; -import org.neo4j.kernel.impl.api.TransactionCommitProcess; -import org.neo4j.kernel.impl.api.TransactionRepresentationCommitProcess; -import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; -import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; import org.neo4j.kernel.impl.api.index.RemoveOrphanConstraintIndexesOnStartup; import org.neo4j.kernel.impl.constraints.ConstraintSemantics; import org.neo4j.kernel.impl.constraints.StandardConstraintSemantics; @@ -58,12 +51,9 @@ import org.neo4j.kernel.impl.locking.ResourceTypes; import org.neo4j.kernel.impl.locking.community.CommunityLockManger; import org.neo4j.kernel.impl.logging.LogService; -import org.neo4j.kernel.impl.store.NeoStores; import org.neo4j.kernel.impl.storemigration.ConfigMapUpgradeConfiguration; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; -import org.neo4j.kernel.impl.transaction.log.TransactionAppender; import org.neo4j.kernel.impl.transaction.state.DataSourceManager; -import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; import org.neo4j.kernel.lifecycle.LifeSupport; import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.kernel.lifecycle.LifecycleListener; @@ -105,7 +95,7 @@ public CommunityEditionModule( PlatformModule platformModule ) dependencies.satisfyDependency( createKernelData( fileSystem, pageCache, storeDir, config, graphDatabaseFacade, life ) ); - commitProcessFactory = createCommitProcessFactory(); + commitProcessFactory = new CommunityCommitProcessFactory(); headerInformationFactory = createHeaderInformationFactory(); @@ -159,30 +149,6 @@ private UsageDataKeys.Edition determineEdition() } - public static CommitProcessFactory createCommitProcessFactory() - { - return new CommitProcessFactory() - { - @Override - public TransactionCommitProcess create( TransactionAppender appender, - KernelHealth kernelHealth, NeoStores neoStores, - TransactionRepresentationStoreApplier storeApplier, - NeoStoreInjectedTransactionValidator txValidator, - IndexUpdatesValidator indexUpdatesValidator, - Config config ) - { - if ( config.get( GraphDatabaseSettings.read_only ) ) - { - return new ReadOnlyTransactionCommitProcess(); - } - else - { - return new TransactionRepresentationCommitProcess( appender, storeApplier, indexUpdatesValidator ); - } - } - }; - } - protected SchemaWriteGuard createSchemaWriteGuard() { return new SchemaWriteGuard() diff --git a/community/kernel/src/test/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactoryTest.java b/community/kernel/src/test/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactoryTest.java new file mode 100644 index 0000000000000..d1e33eaa13ecc --- /dev/null +++ b/community/kernel/src/test/java/org/neo4j/kernel/impl/factory/CommunityCommitProcessFactoryTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002-2015 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.impl.factory; + +import org.junit.Test; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; +import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; +import org.neo4j.kernel.impl.transaction.log.TransactionAppender; +import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; + +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.neo4j.helpers.collection.MapUtil.stringMap; + +public class CommunityCommitProcessFactoryTest +{ + @Test + public void createReadOnlyCommitProcess() + { + CommunityCommitProcessFactory factory = new CommunityCommitProcessFactory(); + + Config config = new Config( stringMap( GraphDatabaseSettings.read_only.name(), "true" ) ); + + TransactionCommitProcess commitProcess = factory.create( mock( TransactionAppender.class ), + mock( TransactionRepresentationStoreApplier.class ), mock( NeoStoreInjectedTransactionValidator.class ), + mock( IndexUpdatesValidator.class ), config ); + + assertThat( commitProcess, instanceOf( ReadOnlyTransactionCommitProcess.class ) ); + } + + @Test + public void createRegularCommitProcess() + { + CommunityCommitProcessFactory factory = new CommunityCommitProcessFactory(); + + TransactionCommitProcess commitProcess = factory.create( mock( TransactionAppender.class ), + mock( TransactionRepresentationStoreApplier.class ), mock( NeoStoreInjectedTransactionValidator.class ), + mock( IndexUpdatesValidator.class ), new Config() ); + + assertThat( commitProcess, instanceOf( TransactionRepresentationCommitProcess.class ) ); + } +} diff --git a/community/kernel/src/test/java/org/neo4j/test/NeoStoreDataSourceRule.java b/community/kernel/src/test/java/org/neo4j/test/NeoStoreDataSourceRule.java index a560ea9b5c196..d29ab5292093b 100644 --- a/community/kernel/src/test/java/org/neo4j/test/NeoStoreDataSourceRule.java +++ b/community/kernel/src/test/java/org/neo4j/test/NeoStoreDataSourceRule.java @@ -45,7 +45,7 @@ import org.neo4j.kernel.impl.core.PropertyKeyTokenHolder; import org.neo4j.kernel.impl.core.RelationshipTypeTokenHolder; import org.neo4j.kernel.impl.core.StartupStatisticsProvider; -import org.neo4j.kernel.impl.factory.CommunityEditionModule; +import org.neo4j.kernel.impl.factory.CommunityCommitProcessFactory; import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.store.StoreFactory; import org.neo4j.kernel.impl.storemigration.StoreUpgrader; @@ -92,7 +92,7 @@ public NeoStoreDataSource getDataSource( File storeDir, FileSystemAbstraction fs fs, mock( StoreUpgrader.class ), mock( TransactionMonitor.class ), kernelHealth, mock( PhysicalLogFile.Monitor.class ), TransactionHeaderInformationFactory.DEFAULT, new StartupStatisticsProvider(), mock( NodeManager.class ), null, null, - CommunityEditionModule.createCommitProcessFactory(), mock( PageCache.class ), + new CommunityCommitProcessFactory(), mock( PageCache.class ), mock( ConstraintSemantics.class), new Monitors(), new Tracers( "null", NullLog.getInstance() ) ); return dataSource; diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactory.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactory.java new file mode 100644 index 0000000000000..6122ef9aeb5ae --- /dev/null +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactory.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2002-2015 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.ha.factory; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.ha.DelegateInvocationHandler; +import org.neo4j.kernel.ha.cluster.modeswitch.CommitProcessSwitcher; +import org.neo4j.kernel.ha.cluster.modeswitch.ComponentSwitcherContainer; +import org.neo4j.kernel.ha.com.RequestContextFactory; +import org.neo4j.kernel.ha.com.master.Master; +import org.neo4j.kernel.ha.transaction.TransactionPropagator; +import org.neo4j.kernel.impl.api.CommitProcessFactory; +import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; +import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; +import org.neo4j.kernel.impl.transaction.log.TransactionAppender; +import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; + +import static java.lang.reflect.Proxy.newProxyInstance; + +class HighlyAvailableCommitProcessFactory implements CommitProcessFactory +{ + private final ComponentSwitcherContainer componentSwitcherContainer; + private final Master master; + private final TransactionPropagator transactionPropagator; + private final RequestContextFactory requestContextFactory; + + private final DelegateInvocationHandler commitProcessDelegate = + new DelegateInvocationHandler<>( TransactionCommitProcess.class ); + + HighlyAvailableCommitProcessFactory( ComponentSwitcherContainer componentSwitcherContainer, Master master, + TransactionPropagator transactionPropagator, RequestContextFactory requestContextFactory ) + { + this.componentSwitcherContainer = componentSwitcherContainer; + this.master = master; + this.transactionPropagator = transactionPropagator; + this.requestContextFactory = requestContextFactory; + } + + @Override + public TransactionCommitProcess create( TransactionAppender appender, + TransactionRepresentationStoreApplier storeApplier, NeoStoreInjectedTransactionValidator txValidator, + IndexUpdatesValidator indexUpdatesValidator, Config config ) + { + if ( config.get( GraphDatabaseSettings.read_only ) ) + { + return new ReadOnlyTransactionCommitProcess(); + } + + TransactionCommitProcess commitProcess = new TransactionRepresentationCommitProcess( appender, storeApplier, + indexUpdatesValidator ); + + CommitProcessSwitcher commitProcessSwitcher = new CommitProcessSwitcher( transactionPropagator, + master, commitProcessDelegate, requestContextFactory, txValidator, commitProcess ); + + componentSwitcherContainer.add( commitProcessSwitcher ); + + return (TransactionCommitProcess) newProxyInstance( TransactionCommitProcess.class.getClassLoader(), + new Class[]{TransactionCommitProcess.class}, commitProcessDelegate ); + } +} diff --git a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java index 49f349793b7e5..a8d9b9cb9624b 100644 --- a/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java +++ b/enterprise/ha/src/main/java/org/neo4j/kernel/ha/factory/HighlyAvailableEditionModule.java @@ -60,7 +60,6 @@ import org.neo4j.kernel.GraphDatabaseAPI; import org.neo4j.kernel.IdGeneratorFactory; import org.neo4j.kernel.KernelData; -import org.neo4j.kernel.KernelHealth; import org.neo4j.kernel.NeoStoreDataSource; import org.neo4j.kernel.api.KernelAPI; import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException; @@ -92,7 +91,6 @@ import org.neo4j.kernel.ha.cluster.member.ClusterMembers; import org.neo4j.kernel.ha.cluster.member.HighAvailabilitySlaves; import org.neo4j.kernel.ha.cluster.member.ObservedClusterMembers; -import org.neo4j.kernel.ha.cluster.modeswitch.CommitProcessSwitcher; import org.neo4j.kernel.ha.cluster.modeswitch.ComponentSwitcherContainer; import org.neo4j.kernel.ha.cluster.modeswitch.HighAvailabilityModeSwitcher; import org.neo4j.kernel.ha.cluster.modeswitch.LabelTokenCreatorSwitcher; @@ -119,13 +117,9 @@ import org.neo4j.kernel.ha.transaction.OnDiskLastTxIdGetter; import org.neo4j.kernel.ha.transaction.TransactionPropagator; import org.neo4j.kernel.impl.api.CommitProcessFactory; -import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; import org.neo4j.kernel.impl.api.SchemaWriteGuard; import org.neo4j.kernel.impl.api.TransactionCommitProcess; import org.neo4j.kernel.impl.api.TransactionHeaderInformation; -import org.neo4j.kernel.impl.api.TransactionRepresentationCommitProcess; -import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; -import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; import org.neo4j.kernel.impl.api.index.RemoveOrphanConstraintIndexesOnStartup; import org.neo4j.kernel.impl.core.DelegatingLabelTokenHolder; import org.neo4j.kernel.impl.core.DelegatingPropertyKeyTokenHolder; @@ -146,10 +140,8 @@ import org.neo4j.kernel.impl.storemigration.UpgradeNotAllowedByDatabaseModeException; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; import org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore; -import org.neo4j.kernel.impl.transaction.log.TransactionAppender; import org.neo4j.kernel.impl.transaction.log.TransactionIdStore; import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointer; -import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; import org.neo4j.kernel.impl.util.Dependencies; import org.neo4j.kernel.impl.util.JobScheduler; import org.neo4j.kernel.lifecycle.LifeSupport; @@ -471,16 +463,12 @@ public MasterServer apply( final Master master, ConversationManager conversation platformModule.dependencies.provideDependency( NeoStoreDataSource.class ) ); ComponentSwitcherContainer componentSwitcherContainer = new ComponentSwitcherContainer(); + Supplier storeIdSupplier = () -> dependencies.resolveDependency( NeoStoreDataSource.class ).getStoreId(); + HighAvailabilityModeSwitcher highAvailabilityModeSwitcher = new HighAvailabilityModeSwitcher( - switchToSlaveInstance, switchToMasterInstance, - clusterClient, clusterMemberAvailability, clusterClient, new Supplier() - { - @Override - public StoreId get() - { - return dependencies.resolveDependency( NeoStoreDataSource.class ).getStoreId(); - } - }, config.get( ClusterSettings.server_id ), componentSwitcherContainer, logging ); + switchToSlaveInstance, switchToMasterInstance, clusterClient, clusterMemberAvailability, clusterClient, + storeIdSupplier, config.get( ClusterSettings.server_id ), componentSwitcherContainer, logging ); + exceptionHandlerRef.set( highAvailabilityModeSwitcher ); clusterClient.addBindingListener( highAvailabilityModeSwitcher ); @@ -572,52 +560,22 @@ protected TransactionHeaderInformation createUsing( byte[] additionalHeader ) } private CommitProcessFactory createCommitProcessFactory( Dependencies dependencies, LogService logging, - Monitors monitors, Config config, LifeSupport paxosLife, - ClusterClient clusterClient, ClusterMembers members, - JobScheduler jobScheduler, Master master, - RequestContextFactory requestContextFactory, - ComponentSwitcherContainer componentSwitcherContainer ) + Monitors monitors, Config config, LifeSupport paxosLife, ClusterClient clusterClient, + ClusterMembers members, JobScheduler jobScheduler, Master master, + RequestContextFactory requestContextFactory, ComponentSwitcherContainer componentSwitcherContainer ) { - final DelegateInvocationHandler commitProcessDelegate = - new DelegateInvocationHandler<>( TransactionCommitProcess.class ); + DefaultSlaveFactory slaveFactory = dependencies.satisfyDependency( new DefaultSlaveFactory( + logging.getInternalLogProvider(), monitors, config.get( HaSettings.com_chunk_size ).intValue() ) ); - DefaultSlaveFactory slaveFactory = dependencies.satisfyDependency( - new DefaultSlaveFactory( logging.getInternalLogProvider(), monitors, - config.get( HaSettings.com_chunk_size ).intValue() ) ); - - Slaves slaves = dependencies.satisfyDependency( - paxosLife.add( new HighAvailabilitySlaves( members, clusterClient, slaveFactory ) ) ); + Slaves slaves = dependencies.satisfyDependency( paxosLife.add( new HighAvailabilitySlaves( members, + clusterClient, slaveFactory ) ) ); TransactionPropagator transactionPropagator = new TransactionPropagator( TransactionPropagator.from( config ), logging.getInternalLog( TransactionPropagator.class ), slaves, new CommitPusher( jobScheduler ) ); paxosLife.add( transactionPropagator ); - return new CommitProcessFactory() - { - @Override - public TransactionCommitProcess create( TransactionAppender appender, - KernelHealth kernelHealth, NeoStores neoStores, - TransactionRepresentationStoreApplier storeApplier, - NeoStoreInjectedTransactionValidator txValidator, - IndexUpdatesValidator indexUpdatesValidator, - Config config ) - { - if ( config.get( GraphDatabaseSettings.read_only ) ) - { - return new ReadOnlyTransactionCommitProcess(); - } - - TransactionCommitProcess inner = new TransactionRepresentationCommitProcess( appender, storeApplier, - indexUpdatesValidator ); - CommitProcessSwitcher commitProcessSwitcher = new CommitProcessSwitcher( transactionPropagator, - master, commitProcessDelegate, requestContextFactory, - txValidator, inner ); - componentSwitcherContainer.add( commitProcessSwitcher ); - - return (TransactionCommitProcess) newProxyInstance( TransactionCommitProcess.class.getClassLoader(), - new Class[]{TransactionCommitProcess.class}, commitProcessDelegate ); - } - }; + return new HighlyAvailableCommitProcessFactory( componentSwitcherContainer, master, transactionPropagator, + requestContextFactory ); } private IdGeneratorFactory createIdGeneratorFactory( @@ -661,8 +619,7 @@ private Locks createLockManager( ComponentSwitcherContainer componentSwitcherCon private TokenCreator createRelationshipTypeCreator( Config config, ComponentSwitcherContainer componentSwitcherContainer, - DelegateInvocationHandler masterInvocationHandler, - RequestContextFactory requestContextFactory, + DelegateInvocationHandler masterInvocationHandler, RequestContextFactory requestContextFactory, Supplier kernelProvider ) { if ( config.get( GraphDatabaseSettings.read_only ) ) @@ -678,15 +635,14 @@ private TokenCreator createRelationshipTypeCreator( Config config, RelationshipTypeCreatorSwitcher typeCreatorModeSwitcher = new RelationshipTypeCreatorSwitcher( relationshipTypeCreatorDelegate, masterInvocationHandler, requestContextFactory, kernelProvider, idGeneratorFactory ); + componentSwitcherContainer.add( typeCreatorModeSwitcher ); return relationshipTypeCreator; } - private TokenCreator createPropertyKeyCreator( Config config, - ComponentSwitcherContainer componentSwitcherContainer, + private TokenCreator createPropertyKeyCreator( Config config, ComponentSwitcherContainer componentSwitcherContainer, DelegateInvocationHandler masterDelegateInvocationHandler, - RequestContextFactory requestContextFactory, - Supplier kernelProvider ) + RequestContextFactory requestContextFactory, Supplier kernelProvider ) { if ( config.get( GraphDatabaseSettings.read_only ) ) { @@ -701,15 +657,14 @@ private TokenCreator createPropertyKeyCreator( Config config, PropertyKeyCreatorSwitcher propertyKeyCreatorModeSwitcher = new PropertyKeyCreatorSwitcher( propertyKeyCreatorDelegate, masterDelegateInvocationHandler, requestContextFactory, kernelProvider, idGeneratorFactory ); + componentSwitcherContainer.add( propertyKeyCreatorModeSwitcher ); return propertyTokenCreator; } - private TokenCreator createLabelIdCreator( Config config, - ComponentSwitcherContainer componentSwitcherContainer, + private TokenCreator createLabelIdCreator( Config config, ComponentSwitcherContainer componentSwitcherContainer, DelegateInvocationHandler masterDelegateInvocationHandler, - RequestContextFactory requestContextFactory, - Supplier kernelProvider ) + RequestContextFactory requestContextFactory, Supplier kernelProvider ) { if ( config.get( GraphDatabaseSettings.read_only ) ) { @@ -724,6 +679,7 @@ private TokenCreator createLabelIdCreator( Config config, LabelTokenCreatorSwitcher modeSwitcher = new LabelTokenCreatorSwitcher( labelIdCreatorDelegate, masterDelegateInvocationHandler, requestContextFactory, kernelProvider, idGeneratorFactory ); + componentSwitcherContainer.add( modeSwitcher ); return labelIdCreator; } diff --git a/enterprise/ha/src/test/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactoryTest.java b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactoryTest.java new file mode 100644 index 0000000000000..406f8dcf7b7d5 --- /dev/null +++ b/enterprise/ha/src/test/java/org/neo4j/kernel/ha/factory/HighlyAvailableCommitProcessFactoryTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002-2015 "Neo Technology," + * Network Engine for Objects in Lund AB [http://neotechnology.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package org.neo4j.kernel.ha.factory; + +import org.junit.Test; + +import java.lang.reflect.Proxy; + +import org.neo4j.graphdb.factory.GraphDatabaseSettings; +import org.neo4j.kernel.configuration.Config; +import org.neo4j.kernel.ha.DelegateInvocationHandler; +import org.neo4j.kernel.ha.cluster.modeswitch.ComponentSwitcherContainer; +import org.neo4j.kernel.ha.com.RequestContextFactory; +import org.neo4j.kernel.ha.com.master.Master; +import org.neo4j.kernel.ha.transaction.TransactionPropagator; +import org.neo4j.kernel.impl.api.ReadOnlyTransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionCommitProcess; +import org.neo4j.kernel.impl.api.TransactionRepresentationStoreApplier; +import org.neo4j.kernel.impl.api.index.IndexUpdatesValidator; +import org.neo4j.kernel.impl.transaction.log.TransactionAppender; +import org.neo4j.kernel.impl.transaction.state.NeoStoreInjectedTransactionValidator; + +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.neo4j.helpers.collection.MapUtil.stringMap; + +public class HighlyAvailableCommitProcessFactoryTest +{ + @Test + public void createReadOnlyCommitProcess() + { + HighlyAvailableCommitProcessFactory factory = new HighlyAvailableCommitProcessFactory( + new ComponentSwitcherContainer(), mock( Master.class ), mock( TransactionPropagator.class ), + mock( RequestContextFactory.class ) ); + + Config config = new Config( stringMap( GraphDatabaseSettings.read_only.name(), "true" ) ); + + TransactionCommitProcess commitProcess = factory.create( mock( TransactionAppender.class ), + mock( TransactionRepresentationStoreApplier.class ), mock( NeoStoreInjectedTransactionValidator.class ), + mock( IndexUpdatesValidator.class ), config ); + + assertThat( commitProcess, instanceOf( ReadOnlyTransactionCommitProcess.class ) ); + } + + @Test + public void createRegularCommitProcess() + { + HighlyAvailableCommitProcessFactory factory = new HighlyAvailableCommitProcessFactory( + new ComponentSwitcherContainer(), mock( Master.class ), mock( TransactionPropagator.class ), + mock( RequestContextFactory.class ) ); + + TransactionCommitProcess commitProcess = factory.create( mock( TransactionAppender.class ), + mock( TransactionRepresentationStoreApplier.class ), mock( NeoStoreInjectedTransactionValidator.class ), + mock( IndexUpdatesValidator.class ), new Config() ); + + assertThat( commitProcess, not( instanceOf( ReadOnlyTransactionCommitProcess.class ) ) ); + assertThat( Proxy.getInvocationHandler( commitProcess ), instanceOf( DelegateInvocationHandler.class ) ); + } +}