Skip to content

Commit

Permalink
Fixing bug in restore for core-edge cluster
Browse files Browse the repository at this point in the history
It would previously only allow you to restore a database called
graph.db due to a config change not being passed through.

Also updated backup/restore tests to use the CLI command instead
of manually composing individual commands
  • Loading branch information
Mark Needham committed Jun 30, 2016
1 parent 9f9e19b commit 8364d2f
Show file tree
Hide file tree
Showing 12 changed files with 227 additions and 119 deletions.
Expand Up @@ -46,13 +46,7 @@ public RestoreDatabaseCommand( FileSystemAbstraction fs, File fromPath, Config c
this.fromPath = fromPath; this.fromPath = fromPath;
this.databaseName = databaseName; this.databaseName = databaseName;
this.forceOverwrite = forceOverwrite; this.forceOverwrite = forceOverwrite;
this.databaseDir = configWith( config, databaseName ).get( database_path ).getAbsoluteFile(); this.databaseDir = config.get( database_path ).getAbsoluteFile();

}

public static Config configWith( Config config, String databaseName )
{
return config.with( stringMap( DatabaseManagementSystemSettings.active_database.name(), databaseName ) );
} }


public void execute() throws IOException public void execute() throws IOException
Expand Down
Expand Up @@ -38,6 +38,8 @@
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;


import static org.neo4j.helpers.collection.MapUtil.stringMap;

public class RestoreDatabaseCommandTest public class RestoreDatabaseCommandTest
{ {
@Rule @Rule
Expand All @@ -49,7 +51,7 @@ public void shouldNotCopyOverAndExistingDatabase() throws Exception
// given // given
FileSystemAbstraction fs = new DefaultFileSystemAbstraction(); FileSystemAbstraction fs = new DefaultFileSystemAbstraction();
String databaseName = "to"; String databaseName = "to";
Config config = RestoreDatabaseCommand.configWith( Config.empty(), databaseName); Config config = configWith( Config.empty(), databaseName);


File fromPath = new File( directory.absolutePath(), "from" ); File fromPath = new File( directory.absolutePath(), "from" );
File toPath = config.get( DatabaseManagementSystemSettings.database_path ); File toPath = config.get( DatabaseManagementSystemSettings.database_path );
Expand Down Expand Up @@ -78,7 +80,7 @@ public void shouldThrowExceptionIfBackupDirectoryDoesNotExist() throws Exception
// given // given
FileSystemAbstraction fs = new DefaultFileSystemAbstraction(); FileSystemAbstraction fs = new DefaultFileSystemAbstraction();
String databaseName = "to"; String databaseName = "to";
Config config = RestoreDatabaseCommand.configWith( Config.empty(), databaseName); Config config = configWith( Config.empty(), databaseName);


File fromPath = new File( directory.absolutePath(), "from" ); File fromPath = new File( directory.absolutePath(), "from" );
File toPath = config.get( DatabaseManagementSystemSettings.database_path ); File toPath = config.get( DatabaseManagementSystemSettings.database_path );
Expand Down Expand Up @@ -106,7 +108,7 @@ public void shouldAllowForcedCopyOverAnExistingDatabase() throws Exception
// given // given
FileSystemAbstraction fs = new DefaultFileSystemAbstraction(); FileSystemAbstraction fs = new DefaultFileSystemAbstraction();
String databaseName = "to"; String databaseName = "to";
Config config = RestoreDatabaseCommand.configWith( Config.empty(), databaseName); Config config = configWith( Config.empty(), databaseName);


File fromPath = new File( directory.absolutePath(), "from" ); File fromPath = new File( directory.absolutePath(), "from" );
File toPath = config.get( DatabaseManagementSystemSettings.database_path ); File toPath = config.get( DatabaseManagementSystemSettings.database_path );
Expand All @@ -130,6 +132,11 @@ public void shouldAllowForcedCopyOverAnExistingDatabase() throws Exception
copiedDb.shutdown(); copiedDb.shutdown();
} }


public static Config configWith( Config config, String databaseName )
{
return config.with( stringMap( DatabaseManagementSystemSettings.active_database.name(), databaseName ) );
}

private void createDbAt( File fromPath, int nodesToCreate ) private void createDbAt( File fromPath, int nodesToCreate )
{ {
GraphDatabaseFactory factory = new GraphDatabaseFactory(); GraphDatabaseFactory factory = new GraphDatabaseFactory();
Expand Down
Expand Up @@ -86,11 +86,11 @@
import static org.neo4j.kernel.impl.store.id.IdType.SCHEMA; import static org.neo4j.kernel.impl.store.id.IdType.SCHEMA;
import static org.neo4j.kernel.impl.store.id.IdType.STRING_BLOCK; import static org.neo4j.kernel.impl.store.id.IdType.STRING_BLOCK;


public class ConvertClassicStoreCommand public class ConvertClassicStoreToCoreCommand
{ {
private final ConversionVerifier conversionVerifier; private final ConversionVerifier conversionVerifier;


public ConvertClassicStoreCommand( ConversionVerifier conversionVerifier ) public ConvertClassicStoreToCoreCommand( ConversionVerifier conversionVerifier )
{ {
this.conversionVerifier = conversionVerifier; this.conversionVerifier = conversionVerifier;
} }
Expand Down Expand Up @@ -123,7 +123,7 @@ private StoreMetadata targetMetadata( File databaseDir ) throws IOException
} }
} }


private ClusterSeed changeStoreId( File storeDir, ClusterSeed conversionId ) throws IOException public static ClusterSeed changeStoreId( File storeDir, ClusterSeed conversionId ) throws IOException
{ {
FileSystemAbstraction fs = new DefaultFileSystemAbstraction(); FileSystemAbstraction fs = new DefaultFileSystemAbstraction();
File metadataStore = new File( storeDir, MetaDataStore.DEFAULT_NAME ); File metadataStore = new File( storeDir, MetaDataStore.DEFAULT_NAME );
Expand All @@ -141,7 +141,7 @@ private ClusterSeed changeStoreId( File storeDir, ClusterSeed conversionId ) thr
} }
} }


private StoreId readStoreId( File metadataStore, PageCache pageCache ) throws IOException public static StoreId readStoreId( File metadataStore, PageCache pageCache ) throws IOException
{ {
long creationTime = MetaDataStore.getRecord( pageCache, metadataStore, TIME ); long creationTime = MetaDataStore.getRecord( pageCache, metadataStore, TIME );
long randomNumber = MetaDataStore.getRecord( pageCache, metadataStore, RANDOM_NUMBER ); long randomNumber = MetaDataStore.getRecord( pageCache, metadataStore, RANDOM_NUMBER );
Expand Down
Expand Up @@ -54,7 +54,7 @@ public static void main( String[] incomingArguments ) throws Throwable


Config config = createConfig( homeDir, databaseName, configPath ); Config config = createConfig( homeDir, databaseName, configPath );


new ConvertClassicStoreCommand( new ConversionVerifier() ).convert( new ConvertClassicStoreToCoreCommand( new ConversionVerifier() ).convert(
config.get( DatabaseManagementSystemSettings.database_path ), config.get( DatabaseManagementSystemSettings.database_path ),
config.get( GraphDatabaseSettings.record_format ), config.get( GraphDatabaseSettings.record_format ),
clusterSeed ); clusterSeed );
Expand Down
Expand Up @@ -28,7 +28,7 @@
import java.util.Optional; import java.util.Optional;


import org.neo4j.coreedge.convert.ConversionVerifier; import org.neo4j.coreedge.convert.ConversionVerifier;
import org.neo4j.coreedge.convert.ConvertClassicStoreCommand; import org.neo4j.coreedge.convert.ConvertClassicStoreToCoreCommand;
import org.neo4j.dbms.DatabaseManagementSystemSettings; import org.neo4j.dbms.DatabaseManagementSystemSettings;
import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.Args; import org.neo4j.helpers.Args;
Expand All @@ -42,6 +42,7 @@


import static org.neo4j.dbms.DatabaseManagementSystemSettings.database_path; import static org.neo4j.dbms.DatabaseManagementSystemSettings.database_path;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.record_format; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.record_format;
import static org.neo4j.helpers.collection.MapUtil.stringMap;


public class RestoreExistingClusterCli public class RestoreExistingClusterCli
{ {
Expand All @@ -63,7 +64,7 @@ public static void main( String[] incomingArguments )


try try
{ {
Config config = loadNeo4jConfig( homeDir, configPath ); Config config = loadNeo4jConfig( homeDir, configPath, databaseName );
restoreDatabase( databaseName, fromPath, forceOverwrite, config ); restoreDatabase( databaseName, fromPath, forceOverwrite, config );
convertStore( config, clusterSeed ); convertStore( config, clusterSeed );
} }
Expand All @@ -73,15 +74,20 @@ public static void main( String[] incomingArguments )
} }
} }


private static Config loadNeo4jConfig( File homeDir, String configPath ) private static Config loadNeo4jConfig( File homeDir, String configPath, String databaseName )
{ {
return new ConfigLoader( settings() ).loadConfig( Optional.of( homeDir ), ConfigLoader configLoader = new ConfigLoader( settings() );
Optional.of( new File( configPath, "neo4j.conf" ) ), NullLog.getInstance() ); Config config = configLoader.loadConfig(
Optional.of( homeDir ),
Optional.of( new File( configPath, "neo4j.conf" ) ),
NullLog.getInstance() );

return config.with( stringMap( DatabaseManagementSystemSettings.active_database.name(), databaseName ) );
} }


private static void convertStore( Config config, String seed ) throws IOException, TransactionFailureException private static void convertStore( Config config, String seed ) throws IOException, TransactionFailureException
{ {
ConvertClassicStoreCommand convert = new ConvertClassicStoreCommand( new ConversionVerifier() ); ConvertClassicStoreToCoreCommand convert = new ConvertClassicStoreToCoreCommand( new ConversionVerifier() );
convert.convert( config.get( database_path ), config.get( record_format ), seed ); convert.convert( config.get( database_path ), config.get( record_format ), seed );
} }


Expand Down
Expand Up @@ -28,7 +28,7 @@
import java.util.Optional; import java.util.Optional;


import org.neo4j.coreedge.convert.ConversionVerifier; import org.neo4j.coreedge.convert.ConversionVerifier;
import org.neo4j.coreedge.convert.ConvertClassicStoreCommand; import org.neo4j.coreedge.convert.ConvertClassicStoreToCoreCommand;
import org.neo4j.coreedge.convert.GenerateClusterSeedCommand; import org.neo4j.coreedge.convert.GenerateClusterSeedCommand;
import org.neo4j.dbms.DatabaseManagementSystemSettings; import org.neo4j.dbms.DatabaseManagementSystemSettings;
import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.factory.GraphDatabaseSettings;
Expand All @@ -43,6 +43,7 @@


import static org.neo4j.dbms.DatabaseManagementSystemSettings.database_path; import static org.neo4j.dbms.DatabaseManagementSystemSettings.database_path;
import static org.neo4j.graphdb.factory.GraphDatabaseSettings.record_format; import static org.neo4j.graphdb.factory.GraphDatabaseSettings.record_format;
import static org.neo4j.helpers.collection.MapUtil.stringMap;


public class RestoreNewClusterCli public class RestoreNewClusterCli
{ {
Expand All @@ -63,7 +64,7 @@ public static void main( String[] incomingArguments )


try try
{ {
Config config = loadNeo4jConfig( homeDir, configPath ); Config config = loadNeo4jConfig( homeDir, configPath, databaseName );
restoreDatabase( databaseName, fromPath, forceOverwrite, config ); restoreDatabase( databaseName, fromPath, forceOverwrite, config );
String seed = generateSeed( config ); String seed = generateSeed( config );
convertStore( config, seed ); convertStore( config, seed );
Expand All @@ -75,15 +76,20 @@ public static void main( String[] incomingArguments )
} }
} }


private static Config loadNeo4jConfig( File homeDir, String configPath ) private static Config loadNeo4jConfig( File homeDir, String configPath, String databaseName )
{ {
return new ConfigLoader( settings() ).loadConfig( Optional.of( homeDir ), ConfigLoader configLoader = new ConfigLoader( settings() );
Optional.of( new File( configPath, "neo4j.conf" ) ), NullLog.getInstance() ); Config config = configLoader.loadConfig(
Optional.of( homeDir ),
Optional.of( new File( configPath, "neo4j.conf" ) ),
NullLog.getInstance() );

return config.with( stringMap( DatabaseManagementSystemSettings.active_database.name(), databaseName ) );
} }


private static void convertStore( Config config, String seed ) throws IOException, TransactionFailureException private static void convertStore( Config config, String seed ) throws IOException, TransactionFailureException
{ {
ConvertClassicStoreCommand convert = new ConvertClassicStoreCommand( new ConversionVerifier() ); ConvertClassicStoreToCoreCommand convert = new ConvertClassicStoreToCoreCommand( new ConversionVerifier() );
convert.convert( config.get( database_path ), config.get( record_format ), seed ); convert.convert( config.get( database_path ), config.get( record_format ), seed );
} }


Expand Down
Expand Up @@ -24,23 +24,19 @@
import org.junit.Test; import org.junit.Test;


import java.io.File; import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.stream.Stream; import java.util.stream.Stream;


import org.neo4j.backup.OnlineBackupSettings; import org.neo4j.backup.OnlineBackupSettings;
import org.neo4j.coreedge.TestStoreId; import org.neo4j.coreedge.TestStoreId;
import org.neo4j.coreedge.convert.ConversionVerifier;
import org.neo4j.coreedge.convert.ConvertClassicStoreCommand;
import org.neo4j.coreedge.convert.GenerateClusterSeedCommand;
import org.neo4j.coreedge.discovery.Cluster; import org.neo4j.coreedge.discovery.Cluster;
import org.neo4j.coreedge.server.CoreEdgeClusterSettings; import org.neo4j.coreedge.server.CoreEdgeClusterSettings;
import org.neo4j.coreedge.server.core.CoreGraphDatabase; import org.neo4j.coreedge.server.core.CoreGraphDatabase;
import org.neo4j.dbms.DatabaseManagementSystemSettings;
import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.factory.GraphDatabaseSettings; import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.helpers.collection.MapUtil; import org.neo4j.helpers.collection.MapUtil;
Expand All @@ -49,7 +45,10 @@
import org.neo4j.kernel.configuration.Settings; import org.neo4j.kernel.configuration.Settings;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacade; import org.neo4j.kernel.impl.factory.GraphDatabaseFacade;
import org.neo4j.kernel.impl.store.format.standard.StandardV3_0; import org.neo4j.kernel.impl.store.format.standard.StandardV3_0;
import org.neo4j.restore.RestoreDatabaseCommand; import org.neo4j.restore.RestoreClusterCliTest;
import org.neo4j.restore.RestoreClusterUtils;
import org.neo4j.restore.RestoreExistingClusterCli;
import org.neo4j.restore.RestoreNewClusterCli;
import org.neo4j.test.DbRepresentation; import org.neo4j.test.DbRepresentation;
import org.neo4j.test.coreedge.ClusterRule; import org.neo4j.test.coreedge.ClusterRule;
import org.neo4j.test.rule.SuppressOutput; import org.neo4j.test.rule.SuppressOutput;
Expand All @@ -59,9 +58,10 @@
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import static org.neo4j.backup.BackupEmbeddedIT.runBackupToolFromOtherJvmToGetExitCode; import static org.neo4j.backup.BackupEmbeddedIT.runBackupToolFromOtherJvmToGetExitCode;
import static org.neo4j.coreedge.TestStoreId.assertAllStoresHaveTheSameStoreId; import static org.neo4j.coreedge.TestStoreId.assertAllStoresHaveTheSameStoreId;
import static org.neo4j.dbms.DatabaseManagementSystemSettings.database_path;
import static org.neo4j.graphdb.Label.label; import static org.neo4j.graphdb.Label.label;
import static org.neo4j.helpers.collection.MapUtil.stringMap; import static org.neo4j.helpers.collection.MapUtil.stringMap;
import static org.neo4j.restore.ArgsBuilder.args;
import static org.neo4j.restore.ArgsBuilder.toArray;


public class BackupCoreIT public class BackupCoreIT
{ {
Expand Down Expand Up @@ -143,16 +143,17 @@ public void makeSureCoreClusterCanBeRestoredFromABackup() throws Throwable
TestStoreId storeId = TestStoreId.readStoreId( dbPaths.get( 0 ), fs ); TestStoreId storeId = TestStoreId.readStoreId( dbPaths.get( 0 ), fs );


// when // when
File initialStoreDir = cluster.coreServerStoreDirectory( 0 ); StringBuilder output = RestoreClusterUtils.execute( () -> RestoreNewClusterCli.main( toArray( args()
restoreDatabase( backupPath, initialStoreDir ); .homeDir( cluster.homeDir( 0 ) ).config( cluster.homeDir( 0 ) ).from( backupPath )
String conversionMetadata = new GenerateClusterSeedCommand().generate( initialStoreDir).getConversionId(); .database( "graph.db" ).force().build() ) ) );


ConvertClassicStoreCommand convertClassicStoreCommand = new ConvertClassicStoreCommand( new ConversionVerifier() ); String seed = RestoreClusterCliTest.extractSeed( output );
for ( int i = 0; i < numberOfCoreServers; i++ )
for ( int i = 1; i < numberOfCoreServers; i++ )
{ {
File coreStoreDir = cluster.coreServerStoreDirectory( i ); File homeDir = cluster.homeDir( i );
restoreDatabase( backupPath, coreStoreDir ); RestoreClusterUtils.execute( () -> RestoreExistingClusterCli.main( toArray( args().homeDir( homeDir )
convertClassicStoreCommand.convert( coreStoreDir, StandardV3_0.NAME , conversionMetadata ); .config( homeDir ).from( backupPath ).database( "graph.db" ).seed( seed ).force().build() ) ) );
} }


cluster.start(); cluster.start();
Expand All @@ -170,13 +171,6 @@ public void makeSureCoreClusterCanBeRestoredFromABackup() throws Throwable
assertNotEquals( storeId, afterRestoreStoreId ); assertNotEquals( storeId, afterRestoreStoreId );
} }


private void restoreDatabase( File backupPath, File coreStoreDir ) throws IOException
{
DefaultFileSystemAbstraction fs = new DefaultFileSystemAbstraction();
Config config = Config.empty().with( stringMap( database_path.name(), coreStoreDir.getAbsolutePath() ) );
new RestoreDatabaseCommand( fs, backupPath, config, "graph.db", true ).execute();
}

static CoreGraphDatabase createSomeData( Cluster cluster ) throws TimeoutException, InterruptedException static CoreGraphDatabase createSomeData( Cluster cluster ) throws TimeoutException, InterruptedException
{ {
return cluster.coreTx( ( db, tx ) -> { return cluster.coreTx( ( db, tx ) -> {
Expand Down
Expand Up @@ -53,7 +53,6 @@
import org.neo4j.kernel.GraphDatabaseDependencies; import org.neo4j.kernel.GraphDatabaseDependencies;
import org.neo4j.kernel.configuration.Config; import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacade; import org.neo4j.kernel.impl.factory.GraphDatabaseFacade;
import org.neo4j.kernel.impl.store.format.RecordFormat;
import org.neo4j.kernel.impl.store.format.standard.StandardV3_0; import org.neo4j.kernel.impl.store.format.standard.StandardV3_0;
import org.neo4j.kernel.internal.DatabaseHealth; import org.neo4j.kernel.internal.DatabaseHealth;
import org.neo4j.logging.Level; import org.neo4j.logging.Level;
Expand Down Expand Up @@ -120,14 +119,19 @@ public void start() throws InterruptedException, ExecutionException


public File coreServerStoreDirectory( int serverId ) public File coreServerStoreDirectory( int serverId )
{ {
return coreServerStoreDirectory( parentDir, serverId ); return coreServerStoreDirectory( homeDir( serverId ) );
} }


public static File coreServerStoreDirectory( File parentDir, int serverId ) public File homeDir( int serverId )
{ {
return new File( parentDir, "server-core-" + serverId ); return new File( parentDir, "server-core-" + serverId );
} }


public static File coreServerStoreDirectory( File neo4jHome )
{
return new File( new File( new File( neo4jHome, "data" ), "databases" ), "graph.db" );
}

public static File edgeServerStoreDirectory( File parentDir, int serverId ) public static File edgeServerStoreDirectory( File parentDir, int serverId )
{ {
return new File( parentDir, "server-edge-" + serverId ); return new File( parentDir, "server-edge-" + serverId );
Expand Down Expand Up @@ -238,8 +242,9 @@ private CoreGraphDatabase startCoreServer( int serverId, int clusterSize, List<A
params.put( entry.getKey(), entry.getValue().apply( serverId ) ); params.put( entry.getKey(), entry.getValue().apply( serverId ) );
} }


final File storeDir = coreServerStoreDirectory( parentDir, serverId ); File neo4jHome = new File( parentDir, "server-core-" + serverId );
params.put( GraphDatabaseSettings.logs_directory.name(), storeDir.getAbsolutePath() ); final File storeDir = coreServerStoreDirectory( neo4jHome );
params.put( GraphDatabaseSettings.logs_directory.name(), new File(neo4jHome, "logs").getAbsolutePath() );
return new CoreGraphDatabase( storeDir, params, GraphDatabaseDependencies.newDependencies(), return new CoreGraphDatabase( storeDir, params, GraphDatabaseDependencies.newDependencies(),
discoveryServiceFactory ); discoveryServiceFactory );
} }
Expand Down

0 comments on commit 8364d2f

Please sign in to comment.