Package org.neo4j.webadmin.backup

Source Code of org.neo4j.webadmin.backup.BackupPerformer

package org.neo4j.webadmin.backup;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.neo4j.onlinebackup.Backup;
import org.neo4j.onlinebackup.Neo4jBackup;
import org.neo4j.rest.domain.DatabaseBlockedException;
import org.neo4j.rest.domain.DatabaseLocator;
import org.neo4j.webadmin.domain.BackupFailedException;
import org.neo4j.webadmin.domain.NoBackupFoundationException;
import org.neo4j.webadmin.properties.ServerConfiguration;

public class BackupPerformer
{

    public final static String LOGICAL_LOG_REGEX = "\\.v[0-9]+$";

    /**
     * Keep track of what directories are currently being used, to avoid
     * multiple backup jobs working in the same directory at once.
     */
    private static final Set<File> lockedPaths = Collections.synchronizedSet( new HashSet<File>() );

    public static void doBackup( File backupPath )
            throws NoBackupFoundationException, BackupFailedException,
            DatabaseBlockedException
    {
        ensurePathIsLocked( backupPath );

        try
        {
            // Naive check to see if folder is initialized
            // I don't want to add an all-out check here, it'd be better
            // for the Neo4jBackup class to throw an exception.
            if ( backupPath.listFiles() == null
                 || backupPath.listFiles().length == 0
                 || !( new File( backupPath, "neostore" ) ).exists() )
            {
                throw new NoBackupFoundationException(
                        "No foundation in: " + backupPath.getAbsolutePath() );
            }

            // Perform backup
            GraphDatabaseService genericDb = DatabaseLocator.getGraphDatabase();

            if ( genericDb instanceof EmbeddedGraphDatabase )
            {

                Backup backup = Neo4jBackup.allDataSources(
                        (EmbeddedGraphDatabase) genericDb,
                        backupPath.getAbsolutePath() );

                backup.doBackup();
            }
            else
            {
                throw new UnsupportedOperationException(
                        "Performing backups on non-local databases is currently not supported." );
            }
        }
        catch ( IllegalStateException e )
        {
            throw new NoBackupFoundationException(
                    "No foundation in: " + backupPath.getAbsolutePath() );
        }
        catch ( IOException e )
        {
            throw new BackupFailedException(
                    "IOException while performing backup, see nested.", e );
        }
        finally
        {
            lockedPaths.remove( backupPath );
        }
    }

    public static void doBackupFoundation( File backupPath )
            throws BackupFailedException
    {
        ensurePathIsLocked( backupPath );

        try
        {

            File mainDbPath = new File( DatabaseLocator.getDatabaseLocation() ).getAbsoluteFile();

            setupBackupFolders( backupPath );

            boolean wasRunning = DatabaseLocator.databaseIsRunning();

            if ( wasRunning )
            {
                DatabaseLocator.shutdownAndBlockGraphDatabase();
            }

            cpTree( mainDbPath, backupPath );

            ServerConfiguration.getInstance().set( "keep_logical_logs", "true" );

            if ( wasRunning )
            {
                DatabaseLocator.unblockGraphDatabase();
                DatabaseLocator.getGraphDatabase();
            }
        }
        catch ( IOException e )
        {
            throw new BackupFailedException(
                    "IOException while creating backup foundation, see nested.",
                    e );
        }
        catch ( DatabaseBlockedException e )
        {
            e.printStackTrace();
        }
        finally
        {
            lockedPaths.remove( backupPath );
        }
    }

    //
    // INTERNALS
    //

    /**
     * Creates any folders not existing on the backupPath, deletes any files in
     * the bottom folder.
     */
    private static void setupBackupFolders( File backupPath )
    {
        // Delete any pre-existing files in backup folder (if it is a folder)
        // if ( backupPath.exists() )
        // {
        // if ( backupPath.isDirectory() )
        // {
        // delTree( backupPath );
        // }
        //
        // backupPath.delete();
        // }

        // Create new, empty folder
        backupPath.mkdirs();
    }

    /**
     * Try to add a given file to the lockedPaths set.
     *
     * @param path
     * @return true if path was added, false if path was already locked.
     */
    private static synchronized boolean lockPath( File path )
    {
        if ( lockedPaths.contains( path ) )
        {
            return false;
        }
        else
        {
            lockedPaths.add( path );
            return true;
        }
    }

    /**
     * Runs until it is able to lock a given path.
     *
     * @param path
     */
    private static void ensurePathIsLocked( File path )
    {
        try
        {
            while ( !lockPath( path ) )
            {
                Thread.sleep( 13 );
            }
        }
        catch ( Exception e )
        {
            throw new RuntimeException( e );
        }
    }

    /**
     * Copy a file system folder/file tree from one spot to another. This
     * implementation will ignore copying logical logs.
     *
     * @param src
     * @param target
     * @throws IOException
     */
    private static void cpTree( File src, File target ) throws IOException
    {
        if ( src.isDirectory() )
        {

            if ( !target.exists() )
            {
                target.mkdir();
            }

            for ( File childFile : src.listFiles() )
            {
                // Ignore logical log files
                if ( !childFile.getName().matches( LOGICAL_LOG_REGEX ) )
                {
                    cpTree( childFile, new File( target, childFile.getName() ) );
                }
            }
        }
        else
        {
            InputStream in = new FileInputStream( src );
            OutputStream out = new FileOutputStream( target );

            byte[] buf = new byte[1024];

            int len;

            while ( ( len = in.read( buf ) ) > 0 )
            {
                out.write( buf, 0, len );
            }

            in.close();
            out.close();
        }
    }

}
TOP

Related Classes of org.neo4j.webadmin.backup.BackupPerformer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.