Author: frm
Date: Thu Sep 29 16:09:48 2016
New Revision: 1762801

URL: http://svn.apache.org/viewvc?rev=1762801&view=rev
Log:
OAK-4843 - Split the backup and restore code in API and implementation packages

Contribution by Andrei Dulceanu.

Added:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java
   (with props)
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java
   (with props)
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java
   (with props)
Removed:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackupRestore.java
Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Backup.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Restore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/backup/FileStoreBackupTest.java

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java?rev=1762801&r1=1762800&r2=1762801&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreBackup.java
 Thu Sep 29 16:09:48 2016
@@ -16,108 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.jackrabbit.oak.backup;
 
-import static 
org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
-
 import java.io.File;
 import java.io.IOException;
 
-import javax.annotation.Nonnull;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Suppliers;
-import org.apache.jackrabbit.oak.segment.Compactor;
 import org.apache.jackrabbit.oak.segment.Revisions;
-import org.apache.jackrabbit.oak.segment.SegmentBufferWriter;
-import org.apache.jackrabbit.oak.segment.SegmentNodeState;
 import org.apache.jackrabbit.oak.segment.SegmentReader;
-import org.apache.jackrabbit.oak.segment.SegmentWriter;
-import org.apache.jackrabbit.oak.segment.WriterCacheManager;
-import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
-import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
-import org.apache.jackrabbit.oak.segment.file.tooling.BasicReadOnlyBlobStore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FileStoreBackup {
-
-    private static final Logger log = LoggerFactory
-            .getLogger(FileStoreBackup.class);
-
-    public static boolean USE_FAKE_BLOBSTORE = Boolean
-            .getBoolean("oak.backup.UseFakeBlobStore");
-
-    public static void backup(@Nonnull SegmentReader reader,
-                              @Nonnull Revisions revisions,
-                              @Nonnull File destination)
-            throws IOException, InvalidFileStoreVersionException {
-        Stopwatch watch = Stopwatch.createStarted();
-        SegmentGCOptions gcOptions = SegmentGCOptions.defaultGCOptions()
-                .setOffline();
-
-        FileStoreBuilder builder = fileStoreBuilder(destination)
-                .withDefaultMemoryMapping();
-        if (USE_FAKE_BLOBSTORE) {
-            builder.withBlobStore(new BasicReadOnlyBlobStore());
-        }
-        builder.withGCOptions(gcOptions);
-        FileStore backup = builder.build();
-        SegmentNodeState current = reader.readHeadState(revisions);
-        try {
-            int gen = 0;
-            gen = current.getRecordId().getSegmentId().getGcGeneration();
-            SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
-                    backup,
-                    backup.getTracker(),
-                    backup.getReader(),
-                    "b",
-                    gen
-            );
-            SegmentWriter writer = new SegmentWriter(
-                    backup,
-                    backup.getReader(),
-                    backup.getBlobStore(),
-                    new WriterCacheManager.Default(),
-                    bufferWriter,
-                    backup.getBinaryReferenceConsumer()
-            );
-            Compactor compactor = new Compactor(backup.getReader(), writer,
-                    backup.getBlobStore(), Suppliers.ofInstance(false),
-                    gcOptions);
-            compactor.setContentEqualityCheck(true);
-            SegmentNodeState head = backup.getHead();
-            SegmentNodeState after = compactor.compact(head, current, head);
-            if (after != null) {
-                backup.getRevisions().setHead(head.getRecordId(),
-                        after.getRecordId());
-            }
-        } finally {
-            backup.close();
-            backup = null;
-        }
-
-        FileStoreBuilder builder2 = fileStoreBuilder(destination)
-                .withDefaultMemoryMapping();
-        builder2.withGCOptions(gcOptions);
-        backup = builder2.build();
-        try {
-            cleanup(backup);
-        } finally {
-            backup.close();
-        }
-        watch.stop();
-        log.info("Backup finished in {}.", watch);
-    }
-
-    static boolean cleanup(FileStore f) throws IOException {
-        boolean ok = true;
-        for (File file : f.cleanup()) {
-            ok = ok && file.delete();
-        }
-        return true;
-    }
+
+public interface FileStoreBackup {
+
+    void backup(SegmentReader reader, Revisions revisions, File destination) 
throws IOException, InvalidFileStoreVersionException;
+
+    boolean cleanup(FileStore f) throws IOException;
+
 }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java?rev=1762801&r1=1762800&r2=1762801&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/FileStoreRestore.java
 Thu Sep 29 16:09:48 2016
@@ -16,96 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.jackrabbit.oak.backup;
 
-import static 
org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.defaultGCOptions;
-import static 
org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
-
 import java.io.File;
 import java.io.IOException;
 
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Suppliers;
-import org.apache.jackrabbit.oak.segment.Compactor;
-import org.apache.jackrabbit.oak.segment.SegmentBufferWriter;
-import org.apache.jackrabbit.oak.segment.SegmentNodeState;
-import org.apache.jackrabbit.oak.segment.SegmentWriter;
-import org.apache.jackrabbit.oak.segment.WriterCacheManager;
-import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions;
-import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class FileStoreRestore {
+public interface FileStoreRestore {
+
+    void restore(File source, File destination) throws IOException, 
InvalidFileStoreVersionException;
 
-    private static final Logger log = LoggerFactory
-            .getLogger(FileStoreRestore.class);
+    void restore(File source);
 
-    static int MAX_FILE_SIZE = 256;
-
-    private static final String JOURNAL_FILE_NAME = "journal.log";
-
-    public static void restore(File source, File destination)
-            throws IOException, InvalidFileStoreVersionException {
-        if (!validFileStore(source)) {
-            throw new IOException("Folder " + source
-                    + " is not a valid FileStore directory");
-        }
-
-        FileStore restore = fileStoreBuilder(source).buildReadOnly();
-        Stopwatch watch = Stopwatch.createStarted();
-
-        FileStore store = fileStoreBuilder(destination).build();
-        SegmentNodeState current = store.getHead();
-        try {
-            SegmentNodeState head = restore.getHead();
-            int gen = head.getRecordId().getSegmentId().getGcGeneration();
-            SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
-                    store,
-                    store.getTracker(),
-                    store.getReader(),
-                    "r",
-                    gen
-            );
-            SegmentWriter writer = new SegmentWriter(
-                    store,
-                    store.getReader(),
-                    store.getBlobStore(),
-                    new WriterCacheManager.Default(),
-                    bufferWriter,
-                    store.getBinaryReferenceConsumer()
-            );
-            SegmentGCOptions gcOptions = defaultGCOptions().setOffline();
-            Compactor compactor = new Compactor(store.getReader(), writer,
-                    store.getBlobStore(), Suppliers.ofInstance(false),
-                    gcOptions);
-            compactor.setContentEqualityCheck(true);
-            SegmentNodeState after = compactor.compact(current, head, current);
-            store.getRevisions().setHead(current.getRecordId(),
-                    after.getRecordId());
-        } finally {
-            restore.close();
-            store.close();
-        }
-        watch.stop();
-        log.info("Restore finished in {}.", watch);
-    }
-
-    public static void restore(File source) {
-        log.warn("Restore not available as an online operation.");
-    }
-
-    private static boolean validFileStore(File source) {
-        if (source == null || !source.isDirectory()) {
-            return false;
-        }
-        for (String f : source.list()) {
-            if (JOURNAL_FILE_NAME.equals(f)) {
-                return true;
-            }
-        }
-        return false;
-    }
 }

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java?rev=1762801&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java
 Thu Sep 29 16:09:48 2016
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.backup.impl;
+
+import static 
org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.base.Suppliers;
+import org.apache.jackrabbit.oak.backup.FileStoreBackup;
+import org.apache.jackrabbit.oak.segment.Compactor;
+import org.apache.jackrabbit.oak.segment.Revisions;
+import org.apache.jackrabbit.oak.segment.SegmentBufferWriter;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.SegmentReader;
+import org.apache.jackrabbit.oak.segment.SegmentWriter;
+import org.apache.jackrabbit.oak.segment.WriterCacheManager;
+import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
+import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
+import org.apache.jackrabbit.oak.segment.file.tooling.BasicReadOnlyBlobStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileStoreBackupImpl implements FileStoreBackup {
+
+    private static final Logger log = 
LoggerFactory.getLogger(FileStoreBackupImpl.class);
+
+    public static boolean USE_FAKE_BLOBSTORE = 
Boolean.getBoolean("oak.backup.UseFakeBlobStore");
+
+    @Override
+    public void backup(@Nonnull SegmentReader reader, @Nonnull Revisions 
revisions, @Nonnull File destination) throws IOException, 
InvalidFileStoreVersionException {
+        Stopwatch watch = Stopwatch.createStarted();
+        SegmentGCOptions gcOptions = 
SegmentGCOptions.defaultGCOptions().setOffline();
+
+        FileStoreBuilder builder = 
fileStoreBuilder(destination).withDefaultMemoryMapping();
+
+        if (USE_FAKE_BLOBSTORE) {
+            builder.withBlobStore(new BasicReadOnlyBlobStore());
+        }
+
+        builder.withGCOptions(gcOptions);
+        FileStore backup = builder.build();
+        SegmentNodeState current = reader.readHeadState(revisions);
+
+        try {
+            int gen = current.getRecordId().getSegmentId().getGcGeneration();
+            SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
+                    backup,
+                    backup.getTracker(),
+                    backup.getReader(),
+                    "b",
+                    gen
+            );
+            SegmentWriter writer = new SegmentWriter(
+                    backup,
+                    backup.getReader(),
+                    backup.getBlobStore(),
+                    new WriterCacheManager.Default(),
+                    bufferWriter,
+                    backup.getBinaryReferenceConsumer()
+            );
+            Compactor compactor = new Compactor(
+                    backup.getReader(),
+                    writer,
+                    backup.getBlobStore(),
+                    Suppliers.ofInstance(false),
+                    gcOptions
+            );
+            compactor.setContentEqualityCheck(true);
+            SegmentNodeState head = backup.getHead();
+            SegmentNodeState after = compactor.compact(head, current, head);
+
+            if (after != null) {
+                backup.getRevisions().setHead(head.getRecordId(), 
after.getRecordId());
+            }
+        } finally {
+            backup.close();
+        }
+
+        backup = fileStoreBuilder(destination)
+                .withDefaultMemoryMapping()
+                .withGCOptions(gcOptions)
+                .build();
+
+        try {
+            cleanup(backup);
+        } finally {
+            backup.close();
+        }
+
+        watch.stop();
+        log.info("Backup finished in {}.", watch);
+    }
+
+    @Override
+    public boolean cleanup(FileStore f) throws IOException {
+        boolean ok = true;
+
+        for (File file : f.cleanup()) {
+            ok = ok && file.delete();
+        }
+
+        return true;
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java?rev=1762801&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java
 Thu Sep 29 16:09:48 2016
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.backup.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.System.nanoTime;
+import static 
org.apache.jackrabbit.oak.management.ManagementOperation.Status.formatTime;
+import static org.apache.jackrabbit.oak.management.ManagementOperation.done;
+import static 
org.apache.jackrabbit.oak.management.ManagementOperation.newManagementOperation;
+
+import java.io.File;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executor;
+
+import javax.annotation.Nonnull;
+import javax.management.openmbean.CompositeData;
+
+import org.apache.jackrabbit.oak.api.jmx.FileStoreBackupRestoreMBean;
+import org.apache.jackrabbit.oak.backup.FileStoreBackup;
+import org.apache.jackrabbit.oak.backup.FileStoreRestore;
+import org.apache.jackrabbit.oak.management.ManagementOperation;
+import org.apache.jackrabbit.oak.segment.Revisions;
+import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.segment.SegmentReader;
+
+/**
+ * Default implementation of {@link FileStoreBackupRestoreMBean} based on a
+ * file.
+ */
+public class FileStoreBackupRestoreImpl implements FileStoreBackupRestoreMBean 
{
+
+    private static final String BACKUP_OP_NAME = "Backup";
+
+    private static final String RESTORE_OP_NAME = "Restore";
+
+    private final SegmentNodeStore store;
+
+    private final Revisions revisions;
+
+    private final SegmentReader reader;
+
+    private final File file;
+
+    private final Executor executor;
+
+    private ManagementOperation<String> backupOp = done(BACKUP_OP_NAME, "");
+
+    private ManagementOperation<String> restoreOp = done(RESTORE_OP_NAME, "");
+
+    private final FileStoreBackup fileStoreBackup;
+
+    private final FileStoreRestore fileStoreRestore;
+
+    /**
+     * @param store    store to back up from or restore to
+     * @param file     file to back up to or restore from
+     * @param executor executor for running the back up or restore operation
+     */
+    public FileStoreBackupRestoreImpl(
+            @Nonnull SegmentNodeStore store,
+            @Nonnull Revisions revisions,
+            @Nonnull SegmentReader reader,
+            @Nonnull File file,
+            @Nonnull Executor executor
+    ) {
+        this.store = checkNotNull(store);
+        this.revisions = checkNotNull(revisions);
+        this.reader = checkNotNull(reader);
+        this.file = checkNotNull(file);
+        this.executor = checkNotNull(executor);
+
+        this.fileStoreBackup = new FileStoreBackupImpl();
+        this.fileStoreRestore = new FileStoreRestoreImpl();
+    }
+
+    @Override
+    @Nonnull
+    public synchronized CompositeData startBackup() {
+        if (backupOp.isDone()) {
+            backupOp = newManagementOperation("Backup", new Callable<String>() 
{
+
+                @Override
+                public String call() throws Exception {
+                    long t0 = nanoTime();
+                    fileStoreBackup.backup(reader, revisions, file);
+                    return "Backup completed in " + formatTime(nanoTime() - 
t0);
+                }
+
+            });
+            executor.execute(backupOp);
+        }
+
+        return getBackupStatus();
+    }
+
+    @Override
+    @Nonnull
+    public synchronized CompositeData getBackupStatus() {
+        return backupOp.getStatus().toCompositeData();
+    }
+
+    @Override
+    @Nonnull
+    public synchronized CompositeData startRestore() {
+        if (restoreOp.isDone()) {
+            restoreOp = newManagementOperation("Restore", new 
Callable<String>() {
+
+                @Override
+                public String call() throws Exception {
+                    long t0 = nanoTime();
+                    fileStoreRestore.restore(file);
+                    return "Restore completed in " + formatTime(nanoTime() - 
t0);
+                }
+
+            });
+            executor.execute(restoreOp);
+        }
+
+        return getRestoreStatus();
+    }
+
+    @Override
+    @Nonnull
+    public synchronized CompositeData getRestoreStatus() {
+        return restoreOp.getStatus().toCompositeData();
+    }
+
+    @Override
+    @Nonnull
+    public String checkpoint(long lifetime) {
+        return store.checkpoint(lifetime);
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreBackupRestoreImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java?rev=1762801&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java
 Thu Sep 29 16:09:48 2016
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.backup.impl;
+
+import static 
org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions.defaultGCOptions;
+import static 
org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.base.Suppliers;
+import org.apache.jackrabbit.oak.backup.FileStoreRestore;
+import org.apache.jackrabbit.oak.segment.Compactor;
+import org.apache.jackrabbit.oak.segment.SegmentBufferWriter;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.SegmentWriter;
+import org.apache.jackrabbit.oak.segment.WriterCacheManager;
+import org.apache.jackrabbit.oak.segment.compaction.SegmentGCOptions;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class FileStoreRestoreImpl implements FileStoreRestore {
+
+    private static final Logger log = 
LoggerFactory.getLogger(FileStoreRestoreImpl.class);
+
+    private static final String JOURNAL_FILE_NAME = "journal.log";
+
+    @Override
+    public void restore(File source, File destination) throws IOException, 
InvalidFileStoreVersionException {
+        if (!validFileStore(source)) {
+            throw new IOException("Folder " + source + " is not a valid 
FileStore directory");
+        }
+
+        FileStore restore = fileStoreBuilder(source).buildReadOnly();
+        Stopwatch watch = Stopwatch.createStarted();
+
+        FileStore store = fileStoreBuilder(destination).build();
+        SegmentNodeState current = store.getHead();
+
+        try {
+            SegmentNodeState head = restore.getHead();
+            int gen = head.getRecordId().getSegmentId().getGcGeneration();
+            SegmentBufferWriter bufferWriter = new SegmentBufferWriter(
+                    store,
+                    store.getTracker(),
+                    store.getReader(),
+                    "r",
+                    gen
+            );
+            SegmentWriter writer = new SegmentWriter(
+                    store,
+                    store.getReader(),
+                    store.getBlobStore(),
+                    new WriterCacheManager.Default(),
+                    bufferWriter,
+                    store.getBinaryReferenceConsumer()
+            );
+            SegmentGCOptions gcOptions = defaultGCOptions().setOffline();
+            Compactor compactor = new Compactor(
+                    store.getReader(),
+                    writer,
+                    store.getBlobStore(),
+                    Suppliers.ofInstance(false),
+                    gcOptions
+            );
+            compactor.setContentEqualityCheck(true);
+            SegmentNodeState after = compactor.compact(current, head, current);
+            store.getRevisions().setHead(current.getRecordId(), 
after.getRecordId());
+        } finally {
+            restore.close();
+            store.close();
+        }
+
+        watch.stop();
+        log.info("Restore finished in {}.", watch);
+    }
+
+    @Override
+    public void restore(File source) {
+        log.warn("Restore not available as an online operation.");
+    }
+
+    private boolean validFileStore(File source) {
+        if (source == null || !source.isDirectory()) {
+            return false;
+        }
+
+        String[] children = source.list();
+
+        if (children == null) {
+            return false;
+        }
+
+        for (String f : children) {
+            if (JOURNAL_FILE_NAME.equals(f)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/backup/impl/FileStoreRestoreImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Backup.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Backup.java?rev=1762801&r1=1762800&r2=1762801&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Backup.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Backup.java
 Thu Sep 29 16:09:48 2016
@@ -25,6 +25,7 @@ import java.io.File;
 import java.io.IOException;
 
 import org.apache.jackrabbit.oak.backup.FileStoreBackup;
+import org.apache.jackrabbit.oak.backup.impl.FileStoreBackupImpl;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
 
@@ -51,7 +52,9 @@ public class Backup implements Runnable
 
         private File target;
 
-        private boolean fakeBlobStore = FileStoreBackup.USE_FAKE_BLOBSTORE;
+        private boolean fakeBlobStore = FileStoreBackupImpl.USE_FAKE_BLOBSTORE;
+
+        private final FileStoreBackup fileStoreBackup = new 
FileStoreBackupImpl();
 
         private Builder() {
             // Prevent external instantiation.
@@ -114,16 +117,19 @@ public class Backup implements Runnable
 
     private final boolean fakeBlobStore;
 
+    private final FileStoreBackup fileStoreBackup;
+
     private Backup(Builder builder) {
         this.source = builder.source;
         this.target = builder.target;
         this.fakeBlobStore = builder.fakeBlobStore;
+        this.fileStoreBackup = builder.fileStoreBackup;
     }
 
     @Override
     public void run() {
         try (FileStore fs = newFileStore()) {
-            FileStoreBackup.backup(fs.getReader(), fs.getRevisions(), target);
+            fileStoreBackup.backup(fs.getReader(), fs.getRevisions(), target);
         } catch (Exception e) {
             e.printStackTrace();
         }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Restore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Restore.java?rev=1762801&r1=1762800&r2=1762801&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Restore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/tool/Restore.java
 Thu Sep 29 16:09:48 2016
@@ -22,6 +22,7 @@ import static com.google.common.base.Pre
 import java.io.File;
 
 import org.apache.jackrabbit.oak.backup.FileStoreRestore;
+import org.apache.jackrabbit.oak.backup.impl.FileStoreRestoreImpl;
 
 /**
  * Restore a backup of a segment store into an existing segment store.
@@ -46,6 +47,8 @@ public class Restore implements Runnable
 
         private File target;
 
+        private final FileStoreRestore fileStoreRestore = new 
FileStoreRestoreImpl();
+
         private Builder() {
             // Prevent external instantiation.
         }
@@ -89,15 +92,18 @@ public class Restore implements Runnable
 
     private final File target;
 
+    private final FileStoreRestore fileStoreRestore;
+
     private Restore(Builder builder) {
         this.source = builder.source;
         this.target = builder.target;
+        this.fileStoreRestore = builder.fileStoreRestore;
     }
 
     @Override
     public void run() {
         try {
-            FileStoreRestore.restore(source, target);
+            fileStoreRestore.restore(source, target);
         } catch (Exception e) {
             e.printStackTrace();
         }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/backup/FileStoreBackupTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/backup/FileStoreBackupTest.java?rev=1762801&r1=1762800&r2=1762801&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/backup/FileStoreBackupTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/backup/FileStoreBackupTest.java
 Thu Sep 29 16:09:48 2016
@@ -30,6 +30,8 @@ import java.util.Random;
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.backup.impl.FileStoreBackupImpl;
+import org.apache.jackrabbit.oak.backup.impl.FileStoreRestoreImpl;
 import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
 import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
@@ -64,20 +66,23 @@ public class FileStoreBackupTest {
         FileStore source = newFileStore(src);
         SegmentNodeStore store = SegmentNodeStoreBuilders.builder(source)
                 .build();
+
+        FileStoreBackup fsb = new FileStoreBackupImpl();
+
         try {
             init(store);
             source.flush();
-            FileStoreBackup.backup(source.getReader(), source.getRevisions(), 
destination);
+            fsb.backup(source.getReader(), source.getRevisions(), destination);
             compare(source, destination);
 
             addTestContent(store);
             source.flush();
-            FileStoreBackup.backup(source.getReader(), source.getRevisions(), 
destination);
+            fsb.backup(source.getReader(), source.getRevisions(), destination);
             compare(source, destination);
 
             source.compact();
-            FileStoreBackup.cleanup(source);
-            FileStoreBackup.backup(source.getReader(), source.getRevisions(), 
destination);
+            fsb.cleanup(source);
+            fsb.backup(source.getReader(), source.getRevisions(), destination);
             compare(source, destination);
         } finally {
             source.close();
@@ -89,12 +94,15 @@ public class FileStoreBackupTest {
         FileStore source = newFileStore(src);
         SegmentNodeStore store = SegmentNodeStoreBuilders.builder(source)
                 .build();
+        FileStoreBackup fsb = new FileStoreBackupImpl();
+        FileStoreRestore fsr = new FileStoreRestoreImpl();
+
         init(store);
         source.flush();
-        FileStoreBackup.backup(source.getReader(), source.getRevisions(), 
destination);
+        fsb.backup(source.getReader(), source.getRevisions(), destination);
         source.close();
 
-        FileStoreRestore.restore(destination, src);
+        fsr.restore(destination, src);
         source = newFileStore(src);
         compare(source, destination);
         source.close();
@@ -139,4 +147,5 @@ public class FileStoreBackupTest {
         new Oak(store).with(new OpenSecurityProvider())
                 .with(new InitialContent()).createContentRepository();
     }
+
 }


Reply via email to