All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.io.layout.Neo4jLayout Maven / Gradle / Ivy

/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.neo4j.io.layout;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Objects;
import java.util.stream.Stream;

import org.neo4j.configuration.Config;
import org.neo4j.configuration.GraphDatabaseInternalSettings;
import org.neo4j.configuration.GraphDatabaseSettings;
import org.neo4j.io.fs.FileUtils;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;

/**
 * File layout representation of neo4j instance that provides the ability to reference any store
 * specific file that can be created by particular store implementation.
 * 
* Any file lookup should use provided layout or particular {@link DatabaseLayout database layout}. *
* Neo4J layout represent layout of whole neo4j instance while particular {@link DatabaseLayout database layout} represent single database. * Neo4J layout should be used as a factory of any layouts for particular database. *
* Any user-provided home or store directory will be transformed to canonical file form and any subsequent layout file * lookup should be considered as operations that provide canonical file form. *
* Store lock file is global per store and should be looked from specific store layout. *
* Example of Neo4j layout for store with 2 databases: *
 *  home directory
 *  | \ data directory
 *  | | \ store directory
 *  | | | \ database directory (neo4j, represented by separate database layout)
 *  | | | | \ particular database files
 *  | | | \ database directory (other represented by separate database layout)
 *  | | | | \ particular database files
 *  | | | \ store_lock
 *  | | \ transaction logs directory
 *  | | | \ database transactions directory (neo4j, represented by separate database layout)
 *  | | | | \ particular database transactions files
 *  | | | \ database transactions directory (other represented by separate database layout)
 *  | | | | \ particular database transactions files
 *  | | \ script directory
 *  | | | \ database script directory (neo4j, represented by separate database layout)
 *  | | | | \ particular database script files
 *  | | | \ database script directory (other represented by separate database layout)
 *  | | | | \ particular database script files
 * 
* The current implementation does not keep references to all requested and provided files and requested layouts but can be easily enhanced to do so. *
* Most file & directory locations of the layout can be individually configured using their corresponding setting. * * @see DatabaseLayout */ public final class Neo4jLayout { private static final String STORE_LOCK_FILENAME = "store_lock"; private static final String SERVER_ID_FILENAME = "server_id"; private final Path homeDirectory; private final Path dataDirectory; private final Path databasesRootDirectory; private final Path txLogsRootDirectory; private final Path scriptRootDirectory; public static Neo4jLayout of( Path homeDirectory ) { return of( Config.defaults( GraphDatabaseSettings.neo4j_home, FileUtils.getCanonicalFile( homeDirectory ).toAbsolutePath() ) ); } public static Neo4jLayout of( Config config ) { var homeDirectory = config.get( GraphDatabaseSettings.neo4j_home ); var dataDirectory = config.get( GraphDatabaseSettings.data_directory ); var databasesRootDirectory = config.get( GraphDatabaseInternalSettings.databases_root_path ); var txLogsRootDirectory = config.get( GraphDatabaseSettings.transaction_logs_root_path ); var scriptRootDirectory = config.get( GraphDatabaseSettings.script_root_path ); return new Neo4jLayout( homeDirectory, dataDirectory, databasesRootDirectory, txLogsRootDirectory, scriptRootDirectory ); } public static Neo4jLayout ofFlat( Path homeDirectory ) { var home = homeDirectory.toAbsolutePath(); var config = Config.newBuilder() .set( GraphDatabaseSettings.neo4j_home, home ) .set( GraphDatabaseSettings.data_directory, home ) .set( GraphDatabaseSettings.transaction_logs_root_path, home ) .set( GraphDatabaseInternalSettings.databases_root_path, home ) .build(); return of( config ); } private Neo4jLayout( Path homeDirectory, Path dataDirectory, Path databasesRootDirectory, Path txLogsRootDirectory, Path scriptRootDirectory ) { this.homeDirectory = FileUtils.getCanonicalFile( homeDirectory ); this.dataDirectory = FileUtils.getCanonicalFile( dataDirectory ); this.databasesRootDirectory = FileUtils.getCanonicalFile( databasesRootDirectory ); this.txLogsRootDirectory = FileUtils.getCanonicalFile( txLogsRootDirectory ); this.scriptRootDirectory = FileUtils.getCanonicalFile( scriptRootDirectory ); } /** * Try to return database layouts for directories that located in the current store directory. * Each sub directory of the store directory treated as a separate database directory and database layout wrapper build for that. * * @return database layouts for directories located in current store directory. If no subdirectories exist empty collection is returned. */ public Collection databaseLayouts() { try ( Stream list = Files.list( databasesRootDirectory) ) { return list.filter( Files::isDirectory ).map( directory -> DatabaseLayout.of( this, directory.getFileName().toString() ) ).collect( toList() ); } catch ( NoSuchFileException e ) { return emptyList(); } catch ( IOException e ) { throw new UncheckedIOException( e ); } } /** * Provide layout for a database with provided name. * No assumptions whatsoever should be taken in regards of database location. * Newly created layout should be used to any kind of file related requests in scope of a database. * @param databaseName database name to provide layout for * @return requested database layout */ public DatabaseLayout databaseLayout( String databaseName ) { return DatabaseLayout.of( this, databaseName ); } /** * Databases root directory where all databases are located. * @return all databases root directory */ public Path databasesDirectory() { return databasesRootDirectory; } /** * Neo4J root directory. * @return the root of the Neo4j instance */ public Path homeDirectory() { return homeDirectory; } public Path transactionLogsRootDirectory() { return txLogsRootDirectory; } public Path scriptRootDirectory() { return scriptRootDirectory; } public Path dataDirectory() { return dataDirectory; } public Path storeLockFile() { return databasesRootDirectory.resolve( STORE_LOCK_FILENAME ); } public Path serverIdFile() { return dataDirectory.resolve( SERVER_ID_FILENAME ); } @Override public boolean equals( Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } var that = (Neo4jLayout) o; return Objects.equals( homeDirectory, that.homeDirectory ) && Objects.equals( dataDirectory, that.dataDirectory ) && Objects.equals( databasesRootDirectory, that.databasesRootDirectory ) && Objects.equals( txLogsRootDirectory, that.txLogsRootDirectory ); } @Override public int hashCode() { return Objects.hash( homeDirectory, dataDirectory, databasesRootDirectory, txLogsRootDirectory ); } @Override public String toString() { return String.format( "Neo4JLayout{ homeDir=%s, dataDir=%s, databasesDir=%s, txLogsRootDir=%s}", homeDirectory.toString(), dataDirectory.toString(), databasesRootDirectory.toString(), txLogsRootDirectory.toString() ); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy