Remote logical backup from command line.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 25 Nov 2020 11:07:34 +0000 (12:07 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 25 Nov 2020 11:07:50 +0000 (12:07 +0100)
org.argeo.maintenance/.gitignore
org.argeo.maintenance/src/org/argeo/maintenance/backup/LogicalBackup.java

index 09e3bc9b241c477ea341af9ee029becad0c2148c..bdd97df6dee41ac6ecca8e08b480d209add5fa7c 100644 (file)
@@ -1,2 +1,3 @@
 /bin/
 /target/
+/testBackup/
index a292dcf23fb5d7d7e69d18cdcd0561608a9f14bd..9964b7f53cbf0e1b96a016095cf06f5294279ecd 100644 (file)
@@ -7,6 +7,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
+import java.net.URI;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
@@ -14,6 +15,8 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
@@ -26,12 +29,16 @@ import javax.jcr.PathNotFoundException;
 import javax.jcr.Property;
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
+import javax.jcr.RepositoryFactory;
 import javax.jcr.Session;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.argeo.api.NodeConstants;
 import org.argeo.api.NodeUtils;
+import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory;
+import org.argeo.jcr.JcrException;
 import org.argeo.jcr.JcrUtils;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -81,6 +88,26 @@ public class LogicalBackup implements Runnable {
        }
 
        public void perform() throws RepositoryException, IOException {
+               // software backup
+               if (bundleContext != null)
+                       performSoftwareBackup();
+
+               // data backup
+               Session defaultSession = login(null);
+               try {
+                       String[] workspaceNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames();
+                       workspaces: for (String workspaceName : workspaceNames) {
+                               if ("security".equals(workspaceName))
+                                       continue workspaces;
+                               perform(workspaceName);
+                       }
+               } finally {
+                       JcrUtils.logoutQuietly(defaultSession);
+               }
+
+       }
+
+       public void performSoftwareBackup() throws IOException {
                for (Bundle bundle : bundleContext.getBundles()) {
                        String relativePath = OSGI_BASE + "boot/" + bundle.getSymbolicName() + ".jar";
                        Dictionary<String, String> headers = bundle.getHeaders();
@@ -147,18 +174,6 @@ public class LogicalBackup implements Runnable {
                        }
                }
 
-               Session defaultSession = login(null);
-               try {
-                       String[] workspaceNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames();
-                       workspaces: for (String workspaceName : workspaceNames) {
-                               if ("security".equals(workspaceName))
-                                       continue workspaces;
-                               perform(workspaceName);
-                       }
-               } finally {
-                       JcrUtils.logoutQuietly(defaultSession);
-               }
-
        }
 
        public void perform(String workspaceName) throws RepositoryException, IOException {
@@ -236,6 +251,45 @@ public class LogicalBackup implements Runnable {
        }
 
        protected Session login(String workspaceName) {
-               return NodeUtils.openDataAdminSession(repository, workspaceName);
+               if (bundleContext != null) {// local
+                       return NodeUtils.openDataAdminSession(repository, workspaceName);
+               } else {// remote
+                       try {
+                               return repository.login(workspaceName);
+                       } catch (RepositoryException e) {
+                               throw new JcrException(e);
+                       }
+               }
        }
+
+       public final static void main(String[] args) throws Exception {
+               if (args.length == 0) {
+                       printUsage("No argument");
+                       System.exit(1);
+               }
+               URI uri = new URI(args[0]);
+               Repository repository = createRemoteRepository(uri);
+               Path basePath = args.length > 1 ? Paths.get(args[1]) : Paths.get(System.getProperty("user.dir"));
+               if (!Files.exists(basePath))
+                       Files.createDirectories(basePath);
+               LogicalBackup backup = new LogicalBackup(null, repository, basePath);
+               backup.run();
+       }
+
+       private static void printUsage(String errorMessage) {
+               if (errorMessage != null)
+                       System.err.println(errorMessage);
+               System.out.println("Usage: LogicalBackup <remote URL> [<target directory>]");
+
+       }
+
+       protected static Repository createRemoteRepository(URI uri) throws RepositoryException {
+               RepositoryFactory repositoryFactory = new ClientDavexRepositoryFactory();
+               Map<String, String> params = new HashMap<String, String>();
+               params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString());
+               // TODO make it configurable
+               params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, NodeConstants.SYS_WORKSPACE);
+               return repositoryFactory.getRepository(params);
+       }
+
 }