/*
* Copyright (c) 2009-2010 "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 <http://www.gnu.org/licenses/>.
*/
package org.neo4j.onlinebackup;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.kernel.impl.nioneo.store.UnderlyingStorageException;
import org.neo4j.kernel.impl.transaction.TxModule;
import org.neo4j.kernel.impl.transaction.XaDataSourceManager;
import org.neo4j.kernel.impl.transaction.xaframework.XaDataSource;
/**
* Command line tool to apply new logical logs.
*/
public class ApplyNewLogs
{
private ApplyNewLogs()
{
// no instances
}
/**
* Apply new logs.
*
* @param args destination database path
*/
public static void main( String args[] )
{
if ( args.length != 1 )
{
System.err.println( "Usage: ApplyNewLogs <db path>" );
System.exit( -1 );
}
String destDir = args[0];
if ( !new File( destDir ).exists() )
{
throw new RuntimeException(
"Unable to locate store in[" + destDir + "]" );
}
Map<String,String> params = new HashMap<String, String>();
params.put( "backup_slave", "true" );
EmbeddedGraphDatabase graphDb = new EmbeddedGraphDatabase( destDir );
setupLuceneIfOnClasspath( destDir, graphDb );
XaDataSourceManager xaDsMgr =
graphDb.getConfig().getTxModule().getXaDataSourceManager();
System.out.println( "Starting apply of new logs..." );
for ( XaDataSource xaDs : xaDsMgr.getAllRegisteredDataSources() )
{
xaDs.makeBackupSlave();
System.out.println( "Checking " + xaDs.getName() + " ..." );
long nextVersion = xaDs.getCurrentLogVersion();
boolean logApplied = false;
while ( xaDs.hasLogicalLog( nextVersion ) )
{
try
{
xaDs.applyLog( xaDs.getLogicalLog( nextVersion ) );
logApplied = true;
}
catch ( IOException e )
{
throw new UnderlyingStorageException(
"Unable to recover slave to consistent state", e );
}
nextVersion++;
}
if ( !logApplied )
{
System.out.println( "No new logs for " + xaDs.getName() );
}
}
graphDb.shutdown();
System.out.println( "Apply of new logs completed." );
}
private static final String LUCENE_DS_CLASS =
"org.neo4j.index.lucene.LuceneDataSource";
private static final String LUCENE_FULLTEXT_DS_CLASS =
"org.neo4j.index.lucene.LuceneFulltextDataSource";
private static void setupLuceneIfOnClasspath( String dstDir,
EmbeddedGraphDatabase graphDb )
{
TxModule txModule = graphDb.getConfig().getTxModule();
XaDataSourceManager xaDsMgr = txModule.getXaDataSourceManager();
// LockManager lockManager = graphDb.getConfig().getLockManager();
try
{
// hack since kernel 1.0 unregisters datasources after recovery
Class<?> clazz = Class.forName( LUCENE_FULLTEXT_DS_CLASS );
if ( xaDsMgr.getXaDataSource( "lucene-fulltext" ) == null )
{
Map<Object, Object> params = new HashMap<Object, Object>();
params.put( "dir", dstDir + "/lucene-fulltext" );
txModule.registerDataSource( "lucene-fulltext", clazz.getName(),
"162373".getBytes(), params );
}
clazz = Class.forName( LUCENE_DS_CLASS );
if ( xaDsMgr.getXaDataSource( "lucene" ) == null )
{
Map<Object, Object> params = new HashMap<Object, Object>();
params.put( "dir", dstDir + "/lucene" );
txModule.registerDataSource( "lucene", clazz.getName(),
"262374".getBytes(), params );
}
}
catch ( ClassNotFoundException e )
{
// ok not on classpath
}
}
}