Skip to content

Commit

Permalink
Allow absolute path to be specified for logical_logs_location
Browse files Browse the repository at this point in the history
  • Loading branch information
MishaDemianenko committed Nov 16, 2017
1 parent 4ce4297 commit f5a5135
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 54 deletions.
Expand Up @@ -74,7 +74,6 @@
import static org.neo4j.kernel.configuration.Settings.optionsIgnoreCase;
import static org.neo4j.kernel.configuration.Settings.pathSetting;
import static org.neo4j.kernel.configuration.Settings.range;
import static org.neo4j.kernel.configuration.Settings.relativePathSetting;
import static org.neo4j.kernel.configuration.Settings.setting;

/**
Expand Down Expand Up @@ -435,7 +434,7 @@ public class GraphDatabaseSettings implements LoadableConfig
setting( "unsupported.dbms.enable_native_schema_index", BOOLEAN, TRUE );

@Description( "Location where Neo4j keeps the logical transaction logs." )
public static final Setting<File> logical_logs_location = relativePathSetting( "dbms.tx_log.location", "" );
public static final Setting<File> logical_logs_location = pathSetting( "dbms.tx_log.location", "" );

// Store settings
@Description( "Make Neo4j keep the logical transaction logs for being able to backup the database. " +
Expand Down
Expand Up @@ -331,14 +331,9 @@ public String valueDescription()
};
}

public static Setting<File> relativePathSetting( String name, String defaultValue )
{
return new FileSetting( name, defaultValue, false );
}

public static Setting<File> pathSetting( String name, String defaultValue )
{
return new FileSetting( name, defaultValue, true );
return new FileSetting( name, defaultValue );
}

private static <T> BiFunction<String,Function<String, String>, String> inheritedValue(
Expand Down Expand Up @@ -1327,13 +1322,11 @@ private static class FileSetting extends ScopeAwareSetting<File>
{
private final String name;
private final String defaultValue;
private final boolean absolutePathAllowed;

FileSetting( String name, String defaultValue, boolean absolutePathAllowed )
FileSetting( String name, String defaultValue )
{
this.name = name;
this.defaultValue = defaultValue;
this.absolutePathAllowed = absolutePathAllowed;
}

@Override
Expand Down Expand Up @@ -1372,15 +1365,7 @@ public File apply( Function<String, String> config )

if ( settingFile.isAbsolute() )
{
if ( absolutePathAllowed )
{
return settingFile;
}
else
{
throw new IllegalArgumentException(
format( "Absolute path is not allowed for setting %s.", name() ) );
}
return settingFile;
}
else
{
Expand Down
Expand Up @@ -56,6 +56,15 @@ public void databaseWithTransactionLogsInSeparateRelativeLocation() throws IOExc
verifyTransactionLogs( txDirectory, storeDir );
}

@Test
public void databaseWithTransactionLogsInSeparateAbsoluteLocation() throws IOException
{
File storeDir = testDirectory.graphDbDir();
File txDirectory = testDirectory.directory( "transaction-logs" );
performTransactions( txDirectory.getAbsolutePath(), storeDir );
verifyTransactionLogs( txDirectory, storeDir );
}

private void performTransactions( String txPath, File storeDir ) throws IOException
{
GraphDatabaseService database = new TestGraphDatabaseFactory().newEmbeddedDatabaseBuilder( storeDir )
Expand Down
Expand Up @@ -60,7 +60,6 @@
import static org.neo4j.kernel.configuration.Settings.min;
import static org.neo4j.kernel.configuration.Settings.pathSetting;
import static org.neo4j.kernel.configuration.Settings.range;
import static org.neo4j.kernel.configuration.Settings.relativePathSetting;
import static org.neo4j.kernel.configuration.Settings.setting;

public class SettingsTest
Expand Down Expand Up @@ -107,22 +106,6 @@ public void shouldHaveAUsefulToStringWhichIsUsedAsTheValidValuesInDocumentation(
assertThat( pathSetting( "", NO_DEFAULT ).toString(), containsString( "A filesystem path" ) );
}

@Test( expected = IllegalArgumentException.class )
public void relativePathSettingsDoesNotAllowAbsolutePath()
{
Setting<File> setting = relativePathSetting( "some.settings", new File( "." ).getAbsolutePath() );
Config.defaults().get( setting );
}

@Test
public void relativePathResolvePathAgainstNeo4jHome()
{
Setting<File> setting = relativePathSetting( "some.setting", "test" );
Config config = Config.defaults();
config.augmentDefaults( GraphDatabaseSettings.neo4j_home, "/root" );
assertEquals( "/root/test", config.get( setting ).getAbsolutePath() );
}

@Test
public void testInteger()
{
Expand Down
Expand Up @@ -29,7 +29,6 @@

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.graphdb.mockfs.EphemeralFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.pagecache.PageCache;
Expand All @@ -42,6 +41,7 @@

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.logical_logs_location;

public class RecoveryRequiredCheckerTest
{
Expand All @@ -55,13 +55,11 @@ public class RecoveryRequiredCheckerTest
private final Monitors monitors = new Monitors();
private EphemeralFileSystemAbstraction fileSystem;
private File storeDir;
private File customtransactionLogsLocation;

@Before
public void setup()
{
storeDir = testDirectory.graphDbDir();
customtransactionLogsLocation = new File( storeDir, "tx-logs" );
fileSystem = fileSystemRule.get();
new TestGraphDatabaseFactory().setFileSystem( fileSystem ).newImpermanentDatabase( storeDir ).shutdown();
}
Expand Down Expand Up @@ -108,8 +106,16 @@ public void shouldBeAbleToRecoverBrokenStore() throws Exception
@Test
public void shouldBeAbleToRecoverBrokenStoreWithLogsInSeparateRelativeLocation() throws Exception
{
Config config = Config.defaults( GraphDatabaseSettings.logical_logs_location,
customtransactionLogsLocation.getName() );
File customTransactionLogsLocation = new File( storeDir, "tx-logs" );
Config config = Config.defaults( logical_logs_location, customTransactionLogsLocation.getName() );
recoverBrokenStoreWithConfig( config );
}

@Test
public void shouldBeAbleToRecoverBrokenStoreWithLogsInSeparateAbsoluteLocation() throws Exception
{
File customTransactionLogsLocation = testDirectory.directory( "tx-logs" );
Config config = Config.defaults( logical_logs_location, customTransactionLogsLocation.getAbsolutePath() );
recoverBrokenStoreWithConfig( config );
}

Expand Down
Expand Up @@ -145,12 +145,19 @@ public void shouldGenerateTransactionInformationWhenLogsNotPresent() throws Exce
@Test
public void extractTransactionInformationFromLogsInCustomRelativeLocation() throws Exception
{
// given
File storeDir = directory.graphDbDir();
File customLogLocation = new File( storeDir, "customLogLocation" );
extractTransactionalInformationFromLogs( customLogLocation.getName(), customLogLocation, storeDir );
}

@Test
public void extractTransactionInformationFromLogsInCustomAbsoluteLocation() throws Exception
{
File storeDir = directory.graphDbDir();
File customLogLocation = directory.directory( "customLogLocation" );
extractTransactionalInformationFromLogs( customLogLocation.getAbsolutePath(), customLogLocation, storeDir );
}

private void extractTransactionalInformationFromLogs( String path, File customLogLocation, File storeDir ) throws IOException
{
LogService logService = new SimpleLogService( NullLogProvider.getInstance(), NullLogProvider.getInstance() );
Expand Down
Expand Up @@ -134,6 +134,20 @@ public void buildContextWithCustomLogFilesLocations() throws Throwable
assertEquals( new File( storeDirectory, customLogLocation ), logFiles.getHighestLogFile().getParentFile() );
}

@Test
public void buildContextWithCustomAbsoluteLogFilesLocations() throws Throwable
{
File customLogDirectory = testDirectory.directory( "absoluteCustomLogDirectory" );
Config customLogLocationConfig = Config.defaults( logical_logs_location, customLogDirectory.getAbsolutePath() );
LogFiles logFiles = builder( storeDirectory, fileSystem ).withConfig( customLogLocationConfig )
.withLogVersionRepository( new SimpleLogVersionRepository() )
.withTransactionIdStore( new SimpleTransactionIdStore() ).build();
logFiles.init();
logFiles.start();

assertEquals( customLogDirectory, logFiles.getHighestLogFile().getParentFile() );
}

@Test( expected = NullPointerException.class )
public void failToBuildFullContextWithoutLogVersionRepo() throws IOException
{
Expand Down
Expand Up @@ -25,6 +25,7 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -170,17 +171,15 @@ public void shouldListMetaDataStoreLastWithTxLogs() throws Exception
@Test
public void shouldListTransactionLogsFromCustomLocationWhenConfigured() throws IOException
{
String customFolderName = "customTxFolder";
GraphDatabaseAPI graphDatabase = (GraphDatabaseAPI) new TestGraphDatabaseFactory()
.newEmbeddedDatabaseBuilder( testDirectory.directory( "customDb" ) )
.setConfig( GraphDatabaseSettings.logical_logs_location, customFolderName )
.newGraphDatabase();
NeoStoreDataSource dataSource = graphDatabase.getDependencyResolver().resolveDependency( NeoStoreDataSource.class );
LogFiles logFiles = graphDatabase.getDependencyResolver().resolveDependency( LogFiles.class );
assertTrue( dataSource.listStoreFiles( true ).stream()
.anyMatch( metadata -> metadata.isLogFile() && logFiles.isLogFile( metadata.file() ) ) );
assertEquals( customFolderName, logFiles.logFilesDirectory().getName() );
graphDatabase.shutdown();
String logFilesPath = "customTxFolder";
verifyLogFilesWithCustomPathListing( logFilesPath );
}

@Test
public void shouldListTransactionLogsFromCustomAbsoluteLocationWhenConfigured() throws IOException
{
File customLogLocation = testDirectory.directory( "customLogLocation" );
verifyLogFilesWithCustomPathListing( customLogLocation.getAbsolutePath() );
}

@Test
Expand Down Expand Up @@ -213,6 +212,20 @@ public void shouldListNeostoreFiles() throws Exception
assertEquals( Arrays.asList(values), listedStoreFiles );
}

private void verifyLogFilesWithCustomPathListing( String path ) throws IOException
{
GraphDatabaseAPI graphDatabase = (GraphDatabaseAPI) new TestGraphDatabaseFactory()
.newEmbeddedDatabaseBuilder( testDirectory.directory( "customDb" ) )
.setConfig( GraphDatabaseSettings.logical_logs_location, path )
.newGraphDatabase();
NeoStoreDataSource dataSource = graphDatabase.getDependencyResolver().resolveDependency( NeoStoreDataSource.class );
LogFiles logFiles = graphDatabase.getDependencyResolver().resolveDependency( LogFiles.class );
assertTrue( dataSource.listStoreFiles( true ).stream()
.anyMatch( metadata -> metadata.isLogFile() && logFiles.isLogFile( metadata.file() ) ) );
assertEquals( Paths.get( path ).getFileName().toString(), logFiles.logFilesDirectory().getName() );
graphDatabase.shutdown();
}

private void filesInStoreDirAre( File storeDir, String[] filenames, String[] dirs )
{
ArrayList<File> files = new ArrayList<>();
Expand Down

0 comments on commit f5a5135

Please sign in to comment.