リリースバージョン
私はのNeo4jのAPIソースに掘ったと答えを見つけました。 Neo4jは、logs
ディレクトリのdebug.log
ファイルから前のバージョンを読み出します。データベースが起動されると、バージョンはログファイルにKernel version: (this is where you'll find the version)
として出力されます。たとえば、それは次のようになります。
2017-11-21 06:21:43.460+0000 INFO [o.n.k.i.DiagnosticsManager] Kernel version: 3.3.0,5b700972242a5ec3e0140261120f2845fb3520ad
をあなたがのNeo4jの道DEBUG.LOGを読み出すことができます:
import java.io.File;
import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.kernel.impl.transaction.log.LogTailScanner;
import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile;
import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader;
import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion;
import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader;
public class Neo4jVersionChecker {
//Note that this method needs the store directory NOT the debug.log file
public static String getNeo4jVersion(File storeDir) {
FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
final PhysicalLogFiles logFiles = new PhysicalLogFiles(storeDir, PhysicalLogFile.DEFAULT_NAME, fileSystem);
final LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader = new VersionAwareLogEntryReader<>();
LogTailScanner tailScanner = new LogTailScanner(logFiles, fileSystem, logEntryReader);
LogEntryVersion version = tailScanner.getTailInformation().latestLogEntryVersion;
if(version!=null) {
return version.toString();
} else {
return null;
}
}
}
上記の方法は、最新のKernel version
エントリは上記のものであるdebug.log
ためV3_0_10
を返します。
残念ながら、Neo4jの方法はあまり正確ではありません。ご覧のとおり、debug.log
のKernel version
は3.3.0
で始まりますが、NeoメソッドではV3_0_10
と表示されています。私はこれがNeoが内部的にバージョンを扱う方法と関係があると仮定しています。
しかし、私たちが今のNeo4jは、バージョンを取得する方法を知っているので、我々はより正確な方法で同じことを行うことができます
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.input.ReversedLinesFileReader;
public class VersionChecker {
public static String getVersion(File storeDir) {
File debugLog = new File(storeDir, "logs" + File.separator + "debug.log");
if(debugLog.exists()) {
try {
//The ReversedLinesFileReader reads the last line of a file first and so on
ReversedLinesFileReader reader = new ReversedLinesFileReader(debugLog, StandardCharsets.UTF_8);
//Read last line
String line = reader.readLine();
while(line!=null) {
//Line can't be null at this point
if(line.contains("Kernel version: ")) {
//This line contains the version
line = line.substring(line.indexOf("Kernel version: ")).substring(16); //get rid of everything except the version
line = line.split(",")[0]; //get rid of the second part of the Kernel version that we don't want
return line;
}
//Next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
上記の方法は3.3.0
を返します。もちろん
ストアバージョン
DEBUG.LOGファイルが存在する場合、これらのメソッドの両方のみ動作します。これまでのNeo4jのバージョンにはすべてのバージョンがあります。ストアディレクトリにneostore
ファイルが含まれている限り、store version
を読むことができます。これは、リリースバージョンを読み出すほどうれしくはありませんが、少なくともそれは何かです。そのためには、以下のようになります。
StoreVersionCheck
と呼ばれるNeo4jクラスには、getVersion(File neostoreFile)
という非常に便利なメソッドが含まれています。残念ながらStoreVersionCheck
のインスタンスを初期化するには、PageCache
というインスタンスが必要です。私たちはPageCache
を作ることができるので、それが私たちがやることです。
import java.io.File;
import java.io.IOException;
import java.util.Optional;
import java.util.function.Consumer;
import org.neo4j.graphdb.factory.GraphDatabaseSettings;
import org.neo4j.io.fs.DefaultFileSystemAbstraction;
import org.neo4j.io.fs.FileSystemAbstraction;
import org.neo4j.io.pagecache.PageCache;
import org.neo4j.kernel.configuration.Config;
import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory;
import org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory;
import org.neo4j.kernel.impl.storemigration.StoreVersionCheck;
import org.neo4j.kernel.impl.util.Neo4jJobScheduler;
import org.neo4j.kernel.monitoring.Monitors;
import org.neo4j.kernel.monitoring.tracing.Tracers;
import org.neo4j.logging.Log;
import org.neo4j.logging.Logger;
import org.neo4j.scheduler.JobScheduler;
public class StoreVersionChecker {
public static String getStoreVersion(File storeDir) {
File storeFile = new File(storeDir, "neostore");
if(!storeFile.exists()) {
return null;
}
StoreVersionCheck check = new StoreVersionCheck(buildPageCache());
try {
Optional<String> version = check.getVersion(storeFile);
if(version.isPresent()) {
return version.get();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static PageCache buildPageCache() {
FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
Config config = Config.defaults();
Log pageCacheLog = new DummyLog();
String desiredImplementationName = config.get(GraphDatabaseFacadeFactory.Configuration.tracer);
Monitors monitors = new Monitors();
JobScheduler jobScheduler = new Neo4jJobScheduler();
Tracers tracers = new Tracers(desiredImplementationName, new DummyLog(), monitors, jobScheduler);
ConfiguringPageCacheFactory pageCacheFactory = new ConfiguringPageCacheFactory(fileSystem, config, tracers.pageCacheTracer, tracers.pageCursorTracerSupplier, pageCacheLog);
PageCache pageCache = pageCacheFactory.getOrCreatePageCache();
if (config.get(GraphDatabaseSettings.dump_configuration))
{
pageCacheFactory.dumpConfiguration();
}
return pageCache;
}
//We need this so we can give the Tracers a Log
private static class DummyLog implements Log {
@Override
public boolean isDebugEnabled() {return false;}
@Override
public Logger debugLogger() {return null;}
@Override
public void debug(String message) {}
@Override
public void debug(String message, Throwable throwable) {}
@Override
public void debug(String format, Object... arguments) {}
@Override
public Logger infoLogger() {return null;}
@Override
public void info(String message) {}
@Override
public void info(String message, Throwable throwable) {}
@Override
public void info(String format, Object... arguments) {}
@Override
public Logger warnLogger() {return null;}
@Override
public void warn(String message) {}
@Override
public void warn(String message, Throwable throwable) {}
@Override
public void warn(String format, Object... arguments) {}
@Override
public Logger errorLogger() {return null;}
@Override
public void error(String message) {}
@Override
public void error(String message, Throwable throwable) {}
@Override
public void error(String format, Object... arguments) {}
@Override
public void bulk(Consumer<Log> consumer) {}
}
}