JackRabbitのリポジトリをファイルからDBに移行する
コンテンツリポジトリのJava API(JCR)実装であるJackRabbitのリポジトリを移行しようとしてハマったのでメモ。
参考リンク
- http://wiki.apache.org/jackrabbit/BackupAndMigration
- http://stackoverflow.com/questions/7379638/how-to-snapshot-backup-restore-from-jcr-java-content-repository
- http://stackoverflow.com/questions/10006617/jcr-jackrabbit-repository-tools
- http://jackrabbit.apache.org/standalone-server.html#StandaloneServer-Backupandmigration
を見ると、JackRabbitの機能でXMLでExportしてImportする方法とかが紹介されている。しかし、試すとうまく移行できない。
今回はリポジトリ内の特定ノードだけ移行したいのではなく、リポジトリを丸ごと移行したい。正確には、データストアとしてファイルシステムを使っていたのを、データベースにただ変更したいだけ。ファイルシステムのリポジトリ --> データベースのリポジトリに変換したいだけなのだが、Export、Importツールは特定ノードに移行には使えそうだが、リポジトリ丸ごととなるとどうもうまく動いてくれない。
結局のところ、リポジトリ丸ごと移行であれば、JackRabbitに用意されているRepositoryCopier APIを使うのがよさそうです。
ただし、JackRabbitのバグなのか、そのままこのAPIを使用するとコピーの途中で「com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'deadbeef-face-babe-cafe-babecafebabe' for key ...」と一意制約違反によるエラーが発生して最後まで完了しない現象となった。どうも、本来であればUPDATE文を発行すべきところをINSERT文で更新しようとしてエラーとなっているようです。
というわけで、JackRabbitにちょっとしたパッチをあてつつコピーツールを作成してみた。GitHubで公開しておきます。
使い方
Git cloneでソースを取得し、gradlewでビルドする。
git clone https://github.com/wadahiro/jackrabbit-copy-tool.git gradlew distZip
build/lib/jackrabbit-copy-tool-{version}.zipが作成されるので、これをJackRabbitのデータを置いているサーバにインストールする。unzipで解凍するだけ。
以下のコマンドでリポジトリのコピーを実行する。パラメータとして、コピー元の設定ファイル・ディレクトリ、コピー先の設定ファイル・ディレクトリを指定すること。
cd jackrabbit-copy-tool/bin/ jackrabbit-copy-tool -sc /jackRabbitDir/repository.xml -sd /jackRabbitDir/home -tc /anotherJackRabbitDir/repository.xml -td /anotherJackRabbitDir/home