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 cbc6d3b56777c..9939906334552 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/NeoStoreDataSource.java @@ -338,7 +338,7 @@ public NeoStoreDataSource( RecordFormats formats ) { this.storeDir = storeDir; - this.config = validateSettingsForPageSwapper( config ); + this.config = config; this.tokenNameLookup = tokenNameLookup; this.dependencyResolver = dependencyResolver; this.scheduler = scheduler; @@ -398,36 +398,6 @@ public Iterable all() this.pageCache = pageCache; } - /** - * Custom IO integrations are partially supported, but the features below are not functional yet. - * When those features are available, this check can be removed entirely. - * This will allow us to ship the custom IO integration for experimental use, and protect users from - * using it with the currently unsupported features. i.e using custom IO integration in HA mode. - */ - private Config validateSettingsForPageSwapper( Config config ) - { - if ( config.get( GraphDatabaseSettings.pagecache_swapper ) != null ) - { - if ( config.get( GraphDatabaseSettings.allow_store_upgrade ) ) - { - throw new IllegalArgumentException( "Store upgrade not allowed with custom IO integrations" ); - } - String onlineBackup = config.getParams().get( "dbms.backup.enabled" ); - if ( onlineBackup != null && !onlineBackup.equals( "false" ) ) - { - throw new IllegalArgumentException( "Online Backup not allowed with custom IO integration" ); - } - for ( String configKey : config.getParams().keySet() ) - { - if ( configKey.contains( "ha." ) ) - { - throw new IllegalArgumentException( "HA mode not allowed with custom IO integrations" ); - } - } - } - return config; - } - @Override public void init() { // We do our own internal life management: diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/KernelContext.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/KernelContext.java index 01e1dd69786ab..0e03051715332 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/KernelContext.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/KernelContext.java @@ -22,6 +22,7 @@ import java.io.File; import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.factory.DatabaseInfo; import org.neo4j.kernel.impl.util.DependencySatisfier; @@ -34,4 +35,6 @@ public interface KernelContext DatabaseInfo databaseInfo(); DependencySatisfier dependencySatisfier(); + + boolean customIOConfigurationUsed( Config config ); } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/SimpleKernelContext.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/SimpleKernelContext.java index 182b425f59ad1..3b1782eb7f49f 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/SimpleKernelContext.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/spi/SimpleKernelContext.java @@ -21,7 +21,9 @@ import java.io.File; +import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.impl.factory.DatabaseInfo; import org.neo4j.kernel.impl.util.DependencySatisfier; @@ -64,4 +66,10 @@ public DependencySatisfier dependencySatisfier() { return satisfier; } + + @Override + public boolean customIOConfigurationUsed( Config config ) + { + return config.get( GraphDatabaseSettings.pagecache_swapper ) != null; + } } diff --git a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java index 314cfc1fb0133..a628029c9200a 100644 --- a/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java +++ b/community/kernel/src/main/java/org/neo4j/kernel/impl/storemigration/StoreUpgrader.java @@ -65,6 +65,7 @@ public class StoreUpgrader public static final String MIGRATION_DIRECTORY = "upgrade"; public static final String MIGRATION_LEFT_OVERS_DIRECTORY = "upgrade_backup"; private static final String MIGRATION_STATUS_FILE = "_status"; + public static final String CUSTOM_IO_EXCEPTION_MESSAGE = "Store upgrade not allowed with custom IO integrations"; private final UpgradableDatabase upgradableDatabase; private final MigrationProgressMonitor progressMonitor; @@ -113,6 +114,11 @@ public void migrateIfNeeded( File storeDirectory) throw new UpgradeNotAllowedByConfigurationException(); } + if( customIOConfigurationUsed( config ) ) + { + throw new IllegalArgumentException( CUSTOM_IO_EXCEPTION_MESSAGE ); + } + // One or more participants would like to do migration progressMonitor.started(); @@ -151,6 +157,11 @@ public void migrateIfNeeded( File storeDirectory) progressMonitor.completed(); } + private boolean customIOConfigurationUsed( Config config ) + { + return config.get( GraphDatabaseSettings.pagecache_swapper ) != null; + } + private boolean isUpgradeAllowed() { return config.get( GraphDatabaseSettings.allow_store_upgrade ); diff --git a/community/neo4j/src/test/java/upgrade/PlatformConstraintStoreUpgradeTest.java b/community/neo4j/src/test/java/upgrade/PlatformConstraintStoreUpgradeTest.java index 54ff762436f2f..3658b89149bbc 100644 --- a/community/neo4j/src/test/java/upgrade/PlatformConstraintStoreUpgradeTest.java +++ b/community/neo4j/src/test/java/upgrade/PlatformConstraintStoreUpgradeTest.java @@ -19,40 +19,62 @@ */ package upgrade; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.neo4j.graphdb.factory.GraphDatabaseBuilder; -import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import java.io.File; +import java.io.IOException; + +import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.factory.GraphDatabaseSettings; -import org.neo4j.kernel.configuration.Settings; +import org.neo4j.io.fs.DefaultFileSystemAbstraction; +import org.neo4j.io.fs.FileSystemAbstraction; +import org.neo4j.kernel.impl.store.format.lowlimit.LowLimitV2_2; +import org.neo4j.kernel.impl.storemigration.StoreUpgrader; import org.neo4j.test.TargetDirectory; import org.neo4j.test.TestGraphDatabaseFactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import static org.neo4j.kernel.impl.storemigration.MigrationTestUtils.prepareSampleLegacyDatabase; public class PlatformConstraintStoreUpgradeTest { @Rule public TargetDirectory.TestDirectory storeDir = TargetDirectory.testDirForTest( getClass() ); + private FileSystemAbstraction fileSystem; + private File prepareDir; + private File workingDir; + + @Before + public void setup() + { + fileSystem = new DefaultFileSystemAbstraction(); + prepareDir = storeDir.directory( "prepare" ); + workingDir = storeDir.directory( "working" ); + } + @Test - public void shouldFailToStartIfConfiguredForCAPIDeviceTest() + public void shouldFailToStartWithCustomIOConfigurationTest() throws IOException { - GraphDatabaseBuilder gdBuilder = - new TestGraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir.graphDbDir() ); - gdBuilder.setConfig( GraphDatabaseSettings.allow_store_upgrade, Settings.TRUE ) - .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ); + prepareSampleLegacyDatabase( LowLimitV2_2.STORE_VERSION, fileSystem, workingDir, prepareDir ); try { - gdBuilder.newGraphDatabase(); + createGraphDatabaseService(); fail( "Should not have created database with custom IO configuration and Store Upgrade." ); } catch ( RuntimeException ex ) { - // good - assertEquals( "Store upgrade not allowed with custom IO integrations", ex.getMessage() ); + assertEquals( StoreUpgrader.CUSTOM_IO_EXCEPTION_MESSAGE, ex.getCause().getCause().getMessage() ); } } + + private GraphDatabaseService createGraphDatabaseService() + { + return new TestGraphDatabaseFactory().newEmbeddedDatabaseBuilder( workingDir ) + .setConfig( GraphDatabaseSettings.allow_store_upgrade, "true" ) + .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ).newGraphDatabase(); + } } diff --git a/enterprise/backup/src/main/java/org/neo4j/backup/OnlineBackupExtensionFactory.java b/enterprise/backup/src/main/java/org/neo4j/backup/OnlineBackupExtensionFactory.java index a01b851b3836a..19e0907f08724 100644 --- a/enterprise/backup/src/main/java/org/neo4j/backup/OnlineBackupExtensionFactory.java +++ b/enterprise/backup/src/main/java/org/neo4j/backup/OnlineBackupExtensionFactory.java @@ -23,7 +23,6 @@ import org.neo4j.helpers.Service; import org.neo4j.io.fs.FileSystemAbstraction; -import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.kernel.NeoStoreDataSource; import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.extension.KernelExtensionFactory; @@ -33,6 +32,7 @@ import org.neo4j.kernel.impl.transaction.log.LogicalTransactionStore; import org.neo4j.kernel.impl.transaction.log.TransactionIdStore; import org.neo4j.kernel.impl.transaction.log.checkpoint.CheckPointer; +import org.neo4j.kernel.internal.GraphDatabaseAPI; import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.kernel.monitoring.Monitors; @@ -40,6 +40,7 @@ public class OnlineBackupExtensionFactory extends KernelExtensionFactory { static final String KEY = "online backup"; + static final String CUSTOM_IO_EXCEPTION_MESSAGE = "Online Backup not allowed with custom IO integration"; public interface Dependencies { @@ -78,6 +79,11 @@ public Class getSettingsClass() @Override public Lifecycle newInstance( KernelContext context, Dependencies dependencies ) throws Throwable { + if ( context.customIOConfigurationUsed( dependencies.getConfig() ) ) + { + throw new IllegalArgumentException( CUSTOM_IO_EXCEPTION_MESSAGE ); + } + return new OnlineBackupKernelExtension( dependencies.getConfig(), dependencies.getGraphDatabaseAPI(), dependencies.logService().getInternalLogProvider(), dependencies.monitors(), dependencies.neoStoreDataSource(), diff --git a/enterprise/backup/src/test/java/org/neo4j/backup/PlatformConstraintBackupTest.java b/enterprise/backup/src/test/java/org/neo4j/backup/PlatformConstraintBackupTest.java index c32c76eb0db2a..3aa350f3d2e09 100644 --- a/enterprise/backup/src/test/java/org/neo4j/backup/PlatformConstraintBackupTest.java +++ b/enterprise/backup/src/test/java/org/neo4j/backup/PlatformConstraintBackupTest.java @@ -19,15 +19,17 @@ */ package org.neo4j.backup; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.neo4j.cluster.ClusterSettings; -import org.neo4j.graphdb.factory.GraphDatabaseBuilder; -import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import java.io.File; + +import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.kernel.configuration.Settings; import org.neo4j.test.TargetDirectory; +import org.neo4j.test.TestGraphDatabaseFactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -37,22 +39,33 @@ public class PlatformConstraintBackupTest @Rule public TargetDirectory.TestDirectory storeDir = TargetDirectory.testDirForTest( getClass() ); + private File workingDir; + + @Before + public void setup() + { + workingDir = storeDir.directory( "working" ); + } + @Test - public void shouldFailToStartIfConfiguredForCAPIDeviceTest() + public void shouldFailToStartWithCustomIOConfigurationTest() { - GraphDatabaseFactory graphDatabaseFactory = new GraphDatabaseFactory(); - GraphDatabaseBuilder gdBuilder = graphDatabaseFactory.newEmbeddedDatabaseBuilder( storeDir.graphDbDir() ); - gdBuilder.setConfig( OnlineBackupSettings.online_backup_enabled, Settings.TRUE ) - .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ); try { - gdBuilder.newGraphDatabase(); - fail( "Should not have created database with custom IO configuration and Online Backup." ); + createGraphDatabaseService(); + fail( "Should not have created database with custom IO configuration and online backup." ); } catch ( RuntimeException ex ) { - // good - assertEquals( "Online Backup not allowed with custom IO integration", ex.getMessage() ); + assertEquals( OnlineBackupExtensionFactory.CUSTOM_IO_EXCEPTION_MESSAGE, + ex.getCause().getCause().getMessage() ); } } + + private GraphDatabaseService createGraphDatabaseService() + { + return new TestGraphDatabaseFactory().newEmbeddedDatabaseBuilder( workingDir ) + .setConfig( OnlineBackupSettings.online_backup_enabled, Settings.TRUE ) + .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ).newGraphDatabase(); + } } 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 e10a313c4471f..b64028423cd99 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 @@ -57,9 +57,6 @@ import org.neo4j.io.fs.FileSystemAbstraction; import org.neo4j.io.pagecache.PageCache; import org.neo4j.kernel.AvailabilityGuard; -import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; -import org.neo4j.kernel.internal.GraphDatabaseAPI; -import org.neo4j.kernel.internal.KernelData; import org.neo4j.kernel.NeoStoreDataSource; import org.neo4j.kernel.api.KernelAPI; import org.neo4j.kernel.api.exceptions.InvalidTransactionTypeKernelException; @@ -138,6 +135,7 @@ import org.neo4j.kernel.impl.locking.Locks; import org.neo4j.kernel.impl.logging.LogService; import org.neo4j.kernel.impl.store.StoreId; +import org.neo4j.kernel.impl.store.format.highlimit.HighLimit; import org.neo4j.kernel.impl.store.id.IdGeneratorFactory; import org.neo4j.kernel.impl.store.stats.IdBasedStoreEntityCounters; import org.neo4j.kernel.impl.transaction.TransactionHeaderInformationFactory; @@ -148,6 +146,8 @@ import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader; import org.neo4j.kernel.impl.util.Dependencies; import org.neo4j.kernel.impl.util.JobScheduler; +import org.neo4j.kernel.internal.GraphDatabaseAPI; +import org.neo4j.kernel.internal.KernelData; import org.neo4j.kernel.lifecycle.LifeSupport; import org.neo4j.kernel.lifecycle.Lifecycle; import org.neo4j.kernel.monitoring.ByteCounterMonitor; @@ -166,6 +166,8 @@ public class HighlyAvailableEditionModule extends EditionModule { + public static final String CUSTOM_IO_EXCEPTION_MESSAGE = "HA mode not allowed with custom IO integrations"; + public HighAvailabilityMemberStateMachine memberStateMachine; public ClusterMembers members; @@ -188,6 +190,12 @@ public HighlyAvailableEditionModule( final PlatformModule platformModule ) final LogService logging = platformModule.logging; final Monitors monitors = platformModule.monitors; + //Temporary check for custom IO + if ( customIOConfigurationUsed( platformModule.config ) ) + { + throw new IllegalArgumentException( CUSTOM_IO_EXCEPTION_MESSAGE ); + } + // Set Netty logger InternalLoggerFactory.setDefaultFactory( new NettyLoggerFactory( logging.getInternalLogProvider() ) ); @@ -512,6 +520,12 @@ public void elected( String role, InstanceId instanceId, URI electedMember ) life.add( paxosLife ); } + private boolean customIOConfigurationUsed( Config config ) + { + return config.get( GraphDatabaseSettings.pagecache_swapper ) != null; + } + + private void publishServerId( Config config, UsageData sysInfo ) { sysInfo.set( UsageDataKeys.serverId, config.get( ClusterSettings.server_id ).toString() ); diff --git a/enterprise/ha/src/test/java/org/neo4j/graphdb/factory/PlatformConstraintGraphDatabaseFactoryTest.java b/enterprise/ha/src/test/java/org/neo4j/graphdb/factory/PlatformConstraintGraphDatabaseFactoryTest.java index 04dea8f0fab5c..6a2b38e8ab3a0 100644 --- a/enterprise/ha/src/test/java/org/neo4j/graphdb/factory/PlatformConstraintGraphDatabaseFactoryTest.java +++ b/enterprise/ha/src/test/java/org/neo4j/graphdb/factory/PlatformConstraintGraphDatabaseFactoryTest.java @@ -19,6 +19,7 @@ */ package org.neo4j.graphdb.factory; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -26,10 +27,7 @@ import org.neo4j.cluster.ClusterSettings; import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.kernel.api.index.PreexistingIndexEntryConflictException; -import org.neo4j.kernel.configuration.Config; -import org.neo4j.kernel.ha.HaSettings; -import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase; +import org.neo4j.kernel.ha.factory.HighlyAvailableEditionModule; import org.neo4j.test.TargetDirectory; import static org.junit.Assert.assertEquals; @@ -40,23 +38,34 @@ public class PlatformConstraintGraphDatabaseFactoryTest @Rule public TargetDirectory.TestDirectory storeDir = TargetDirectory.testDirForTest( getClass() ); + private File workingDir; + + @Before + public void setup() + { + workingDir = storeDir.directory( "working" ); + } + @Test - public void shouldFailToStartIfConfiguredForCAPIDeviceTest() + public void shouldFailToStartWithCustomIOConfigurationTest() { - GraphDatabaseBuilder graphDatabaseBuilder = new HighlyAvailableGraphDatabaseFactory(). - newEmbeddedDatabaseBuilder( storeDir.graphDbDir() ) - .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ) - .setConfig( ClusterSettings.initial_hosts, "127.0.0.1:5001" ) - .setConfig( ClusterSettings.server_id, "1" ); try { - graphDatabaseBuilder.newGraphDatabase(); + createGraphDatabaseService(); fail( "Should not have created database with custom IO configuration and HA mode." ); } catch ( RuntimeException ex ) { - // good - assertEquals( "HA mode not allowed with custom IO integrations", ex.getMessage() ); + assertEquals( HighlyAvailableEditionModule.CUSTOM_IO_EXCEPTION_MESSAGE, ex.getMessage() ); } } + + private GraphDatabaseService createGraphDatabaseService() + { + return new TestHighlyAvailableGraphDatabaseFactory().newEmbeddedDatabaseBuilder( workingDir ) + .setConfig( GraphDatabaseSettings.pagecache_swapper, "custom" ) + .setConfig( ClusterSettings.initial_hosts, "127.0.0.1:5001" ) + .setConfig( ClusterSettings.server_id, "1" ).newGraphDatabase(); + } + } diff --git a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java index ddba0290921cf..e7cd7caae6dd5 100644 --- a/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java +++ b/enterprise/kernel/src/main/java/org/neo4j/kernel/impl/enterprise/EnterpriseEditionModule.java @@ -19,6 +19,7 @@ */ package org.neo4j.kernel.impl.enterprise; + import org.neo4j.kernel.impl.constraints.ConstraintSemantics; import org.neo4j.kernel.impl.enterprise.transaction.log.checkpoint.ConfigurableIOLimiter; import org.neo4j.kernel.impl.factory.CommunityEditionModule;