Author: mduerig
Date: Tue Mar 18 10:06:23 2014
New Revision: 1578808
URL: http://svn.apache.org/r1578808
Log:
OAK-1160: Generic interfaces for operation tasks
Default implementations of FileStoreBackupRestoreMBean, BlobGCMBean and
RevisionGCMBean
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java?rev=1578808&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/backup/FileStoreBackupRestore.java
Tue Mar 18 10:06:23 2014
@@ -0,0 +1,146 @@
+/*
+ * 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.plugins.backup;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation of {@link FileStoreBackupRestoreMBean} based on a
file.
+ */
+public class FileStoreBackupRestore implements FileStoreBackupRestoreMBean {
+ private static final Logger log =
LoggerFactory.getLogger(FileStoreBackupRestore.class);
+
+ private final NodeStore store;
+ private final File file;
+ private final ExecutorService executorService;
+
+ private Future<Long> backupOp;
+ private long backupEndTime;
+ private Future<Long> restoreOp;
+ private long restoreEndTime;
+
+ /**
+ * @param store store to back up from or restore to
+ * @param file file to back up to or restore from
+ * @param executorService executor service for running the back up or
restore operation
+ * in the background.
+ */
+ public FileStoreBackupRestore(
+ @Nonnull NodeStore store,
+ @Nonnull File file,
+ @Nonnull ExecutorService executorService) {
+ this.store = checkNotNull(store);
+ this.file = checkNotNull(file);
+ this.executorService = checkNotNull(executorService);
+ }
+
+ @Override
+ public synchronized String startBackup() {
+ if (backupOp != null && !backupOp.isDone()) {
+ return "Backup already running";
+ } else {
+ backupOp = executorService.submit(new Callable<Long>() {
+ @Override
+ public Long call() throws Exception {
+ long t0 = System.nanoTime();
+ FileStoreBackup.backup(store, file);
+ return System.nanoTime() - t0;
+ }
+ });
+ return getBackupStatus();
+ }
+ }
+
+ @Override
+ public synchronized String getBackupStatus() {
+ if (backupOp == null) {
+ return "Backup not started";
+ } else if (backupOp.isCancelled()) {
+ return "Backup cancelled";
+ } else if (backupOp.isDone()) {
+ try {
+ return "Backup completed in " + formatTime(backupOp.get());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "Backup status unknown: " + e.getMessage();
+ } catch (ExecutionException e) {
+ log.error("Backup failed", e.getCause());
+ return "Backup failed: " + e.getCause().getMessage();
+ }
+ } else {
+ return "Backup running";
+ }
+ }
+
+ @Override
+ public synchronized String startRestore() {
+ if (restoreOp != null && !restoreOp.isDone()) {
+ return "Restore already running";
+ } else {
+ restoreOp = executorService.submit(new Callable<Long>() {
+ @Override
+ public Long call() throws Exception {
+ long t0 = System.nanoTime();
+ FileStoreRestore.restore(file, store);
+ return System.nanoTime() - t0;
+ }
+ });
+ return getRestoreStatus();
+ }
+ }
+
+ @Override
+ public synchronized String getRestoreStatus() {
+ if (restoreOp == null) {
+ return "Restore not started";
+ } else if (restoreOp.isCancelled()) {
+ return "Restore cancelled";
+ } else if (restoreOp.isDone()) {
+ try {
+ return "Restore completed in " + formatTime(restoreOp.get());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "Restore status unknown: " + e.getMessage();
+ } catch (ExecutionException e) {
+ log.error("Restore failed", e.getCause());
+ return "Restore failed: " + e.getCause().getMessage();
+ }
+ } else {
+ return "Restore running";
+ }
+ }
+
+ private static String formatTime(long nanos) {
+ return TimeUnit.MINUTES.convert(nanos, TimeUnit.NANOSECONDS) + "
minutes";
+ }
+}
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java?rev=1578808&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/blob/BlobGC.java
Tue Mar 18 10:06:23 2014
@@ -0,0 +1,102 @@
+/*
+ * 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.plugins.blob;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation of {@link BlobGCMBean} based on a {@link
BlobGarbageCollector}.
+ */
+public class BlobGC implements BlobGCMBean {
+ private static final Logger log = LoggerFactory.getLogger(BlobGC.class);
+
+ private final BlobGarbageCollector blobGarbageCollector;
+ private final ExecutorService executorService;
+
+ private Future<Long> gcOp;
+
+ /**
+ * @param blobGarbageCollector Blob garbage collector
+ * @param executorService executor service for running the garbage
collection task
+ * in the background.
+ */
+ public BlobGC(
+ @Nonnull BlobGarbageCollector blobGarbageCollector,
+ @Nonnull ExecutorService executorService) {
+ this.blobGarbageCollector = checkNotNull(blobGarbageCollector);
+ this.executorService = checkNotNull(executorService);
+ }
+
+ @Nonnull
+ @Override
+ public String startBlobGC() {
+ if (gcOp != null && !gcOp.isDone()) {
+ return "Garbage collection already running";
+ } else {
+ gcOp = executorService.submit(new Callable<Long>() {
+ @Override
+ public Long call() throws Exception {
+ long t0 = System.nanoTime();
+ blobGarbageCollector.collectGarbage();
+ return System.nanoTime() - t0;
+ }
+ });
+ return getBlobGCStatus();
+ }
+ }
+
+ @Nonnull
+ @Override
+ public String getBlobGCStatus() {
+ if (gcOp == null) {
+ return "Garbage collection not started";
+ } else if (gcOp.isCancelled()) {
+ return "Garbage collection cancelled";
+ } else if (gcOp.isDone()) {
+ try {
+ return "Garbage collection completed in " +
formatTime(gcOp.get());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "Garbage Collection status unknown: " + e.getMessage();
+ } catch (ExecutionException e) {
+ log.error("Garbage collection failed", e.getCause());
+ return "Garbage collection failed: " +
e.getCause().getMessage();
+ }
+ } else {
+ return "Garbage collection running";
+ }
+ }
+
+ private static String formatTime(long nanos) {
+ return TimeUnit.MINUTES.convert(nanos, TimeUnit.NANOSECONDS) + "
minutes";
+ }
+
+}
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java?rev=1578808&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
(added)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/RevisionGC.java
Tue Mar 18 10:06:23 2014
@@ -0,0 +1,102 @@
+/*
+ * 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.spi.state;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation of {@link RevisionGCMBean} based on a {@code
Runnable}.
+ */
+public class RevisionGC implements RevisionGCMBean {
+ private static final Logger log =
LoggerFactory.getLogger(RevisionGC.class);
+
+ private final Runnable gc;
+ private final ExecutorService executorService;
+
+ private Future<Long> gcOp;
+
+ /**
+ * @param gc Revision garbage collector
+ * @param executorService executor service for running the garbage
collection task
+ * in the background.
+ */
+ public RevisionGC(
+ @Nonnull Runnable gc,
+ @Nonnull ExecutorService executorService) {
+ this.gc = checkNotNull(gc);
+ this.executorService = checkNotNull(executorService);
+ }
+
+
+ @Nonnull
+ @Override
+ public String startRevisionGC() {
+ if (gcOp != null && !gcOp.isDone()) {
+ return "Garbage collection already running";
+ } else {
+ gcOp = executorService.submit(new Callable<Long>() {
+ @Override
+ public Long call() throws Exception {
+ long t0 = System.nanoTime();
+ gc.run();
+ return System.nanoTime() - t0;
+ }
+ });
+ return getRevisionGCStatus();
+ }
+ }
+
+ @Nonnull
+ @Override
+ public String getRevisionGCStatus() {
+ if (gcOp == null) {
+ return "Garbage collection not started";
+ } else if (gcOp.isCancelled()) {
+ return "Garbage collection cancelled";
+ } else if (gcOp.isDone()) {
+ try {
+ return "Garbage collection completed in " +
formatTime(gcOp.get());
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return "Garbage Collection status unknown: " + e.getMessage();
+ } catch (ExecutionException e) {
+ log.error("Garbage collection failed", e.getCause());
+ return "Garbage collection failed: " +
e.getCause().getMessage();
+ }
+ } else {
+ return "Garbage collection running";
+ }
+ }
+
+ private static String formatTime(long nanos) {
+ return TimeUnit.MINUTES.convert(nanos, TimeUnit.NANOSECONDS) + "
minutes";
+ }
+}