Introduce org.argeo.maintenance
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 5 Feb 2018 10:05:24 +0000 (11:05 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 5 Feb 2018 10:05:24 +0000 (11:05 +0100)
Slim down CMS dependencies

43 files changed:
org.argeo.cms/bnd.bnd
org.argeo.cms/src/org/argeo/cms/auth/HttpSessionLoginModule.java
org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java [deleted file]
org.argeo.cms/src/org/argeo/cms/internal/http/HttpConstants.java [new file with mode: 0644]
org.argeo.cms/src/org/argeo/cms/internal/kernel/FirstInit.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java
org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java
org.argeo.maintenance/.classpath [new file with mode: 0644]
org.argeo.maintenance/.gitignore [new file with mode: 0644]
org.argeo.maintenance/.project [new file with mode: 0644]
org.argeo.maintenance/META-INF/.gitignore [new file with mode: 0644]
org.argeo.maintenance/bnd.bnd [new file with mode: 0644]
org.argeo.maintenance/build.properties [new file with mode: 0644]
org.argeo.maintenance/pom.xml [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/MaintenanceException.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AbstractAtomicBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AtomicBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupContext.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupFileSystemManager.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupPurge.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupUtils.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/MySqlBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OpenLdapBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OsCallBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/PostgreSqlBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupContext.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupPurge.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SvnBackup.java [new file with mode: 0644]
org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SystemBackup.java [new file with mode: 0644]
pom.xml

index 9d4c3bb503717e62c5c6b6965e534efa72ee838c..3061a0e510eb29a1af83deffd0dfa7d2c2032142 100644 (file)
@@ -5,9 +5,10 @@ org.h2;resolution:=optional,\
 org.postgresql;resolution:=optional,\
 org.apache.jackrabbit.webdav.server,\
 org.apache.jackrabbit.webdav.jcr,\
-org.eclipse.equinox.http.jetty,\
-org.springframework.context,\
-org.springframework.core.io,\
+org.springframework.context;resolution:=optional,\
+org.springframework.core.io;resolution:=optional,\
+org.springframework.*;resolution:=optional,\
+org.eclipse.gemini.blueprint.*;resolution:=optional\
 org.apache.commons.httpclient.cookie;resolution:=optional,\
 org.osgi.*;version=0.0.0,\
 *
index d2f0fe738d751957b684925d67dfaf895403f829..ccd02b5b2783f8a26535958e7ebdcf5c89b5480b 100644 (file)
@@ -2,6 +2,7 @@ package org.argeo.cms.auth;
 
 import java.io.IOException;
 import java.security.cert.X509Certificate;
+import java.util.Base64;
 import java.util.Collection;
 import java.util.Map;
 import java.util.StringTokenizer;
@@ -16,7 +17,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
 
-import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
@@ -154,7 +154,8 @@ public class HttpSessionLoginModule implements LoginModule {
                                if (basic.equalsIgnoreCase("Basic")) {
                                        try {
                                                // TODO manipulate char[]
-                                               String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8");
+                                               Base64.Decoder decoder = Base64.getDecoder();
+                                               String credentials = new String(decoder.decode(st.nextToken()), "UTF-8");
                                                // log.debug("Credentials: " + credentials);
                                                int p = credentials.indexOf(":");
                                                if (p != -1) {
@@ -170,7 +171,8 @@ public class HttpSessionLoginModule implements LoginModule {
                                        }
                                } else if (basic.equalsIgnoreCase("Negotiate")) {
                                        String spnegoToken = st.nextToken();
-                                       byte[] authToken = Base64.decodeBase64(spnegoToken);
+                                       Base64.Decoder decoder = Base64.getDecoder();
+                                       byte[] authToken = decoder.decode(spnegoToken);
                                        sharedState.put(CmsAuthUtils.SHARED_STATE_SPNEGO_TOKEN, authToken);
                                }
                        }
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/AbstractAtomicBackup.java
deleted file mode 100644 (file)
index d8824ba..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
-import org.argeo.cms.CmsException;
-
-/**
- * Simplify atomic backups implementation, especially by managing VFS.
- */
-public abstract class AbstractAtomicBackup implements AtomicBackup {
-       private String name;
-       private String compression = "bz2";
-
-       protected abstract void writeBackup(FileObject targetFo);
-
-       public AbstractAtomicBackup() {
-       }
-
-       public AbstractAtomicBackup(String name) {
-               this.name = name;
-       }
-
-       public void init() {
-               if (name == null)
-                       throw new CmsException("Atomic backup name must be set");
-       }
-
-       public void destroy() {
-
-       }
-
-       @Override
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts) {
-               if (name == null)
-                       throw new CmsException("Atomic backup name must be set");
-
-               FileObject targetFo = null;
-               try {
-                       if (backupsBase.startsWith("sftp:"))
-                               SftpFileSystemConfigBuilder.getInstance()
-                                               .setStrictHostKeyChecking(opts, "no");
-                       if (compression == null || compression.equals("none"))
-                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
-                                               + backupContext.getRelativeFolder() + '/' + name, opts);
-                       else if (compression.equals("bz2"))
-                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".bz2" + "!" + name, opts);
-                       else if (compression.equals("gz"))
-                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
-                                               + '/' + backupContext.getRelativeFolder() + '/' + name
-                                               + ".gz" + "!" + name, opts);
-                       else
-                               throw new CmsException("Unsupported compression "
-                                               + compression);
-
-                       writeBackup(targetFo);
-
-                       return targetFo.toString();
-               } catch (Exception e) {
-                       throw new CmsException("Cannot backup " + name + " to "
-                                       + targetFo, e);
-               } finally {
-                       BackupUtils.closeFOQuietly(targetFo);
-               }
-       }
-
-       public void setName(String name) {
-               this.name = name;
-       }
-
-       public String getName() {
-               return name;
-       }
-
-       public void setCompression(String compression) {
-               this.compression = compression;
-       }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/AtomicBackup.java
deleted file mode 100644 (file)
index e14344c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Performs the backup of a single component, typically a database dump */
-public interface AtomicBackup {
-       /** Name identifiying this backup */
-       public String getName();
-
-       /**
-        * Retrieves the data of the component in a format that allows to restore
-        * the component
-        * 
-        * @param backupContext
-        *            the context of this backup
-        * @return the VFS URI of the generated file or directory
-        */
-       public String backup(FileSystemManager fileSystemManager,
-                       String backupsBase, BackupContext backupContext,
-                       FileSystemOptions opts);
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupContext.java
deleted file mode 100644 (file)
index 14e7eb4..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.text.DateFormat;
-import java.util.Date;
-
-/**
- * Transient information of a given backup, centralizing common information such
- * as timestamp and location.
- */
-public interface BackupContext {
-       /** Backup date */
-       public Date getTimestamp();
-
-       /** Formatted backup date */
-       public String getTimestampAsString();
-
-       /** System name */
-       public String getSystemName();
-
-       /** Local base */
-       public String getRelativeFolder();
-
-       /** Date format */
-       public DateFormat getDateFormat();
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupFileSystemManager.java
deleted file mode 100644 (file)
index d8d626a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
-import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
-import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
-import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
-import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
-import org.apache.commons.vfs2.provider.ram.RamFileProvider;
-import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
-import org.apache.commons.vfs2.provider.url.UrlFileProvider;
-import org.argeo.cms.CmsException;
-
-/**
- * Programatically configured VFS file system manager which can be declared as a
- * bean and associated with a life cycle (methods
- * {@link DefaultFileSystemManager#init()} and
- * {@link DefaultFileSystemManager#close()}). Supports bz2, file, ram, gzip,
- * ftp, sftp
- */
-public class BackupFileSystemManager extends DefaultFileSystemManager {
-
-       public BackupFileSystemManager() {
-               super();
-               try {
-                       addProvider("file", new DefaultLocalFileProvider());
-                       addProvider("bz2", new Bzip2FileProvider());
-                       addProvider("ftp", new FtpFileProvider());
-                       addProvider("sftp", new SftpFileProvider());
-                       addProvider("gzip", new GzipFileProvider());
-                       addProvider("ram", new RamFileProvider());
-                       setDefaultProvider(new UrlFileProvider());
-               } catch (FileSystemException e) {
-                       throw new CmsException("Cannot configure backup file provider", e);
-               }
-       }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupPurge.java
deleted file mode 100644 (file)
index 75a6b16..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.text.DateFormat;
-
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-
-/** Purges previous backups */
-public interface BackupPurge {
-       /**
-        * Purge the backups identified by these arguments. Although these are the
-        * same fields as a {@link BackupContext} we don't pass it as argument since
-        * we want to use this interface to purge remote backups as well (that is,
-        * with a different base), or outside the scope of a running backup.
-        */
-       public void purge(FileSystemManager fileSystemManager, String base,
-                       String name, DateFormat dateFormat, FileSystemOptions opts);
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/BackupUtils.java
deleted file mode 100644 (file)
index 9a4e91c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backup utilities */
-public class BackupUtils {
-       /** Close a file object quietly even if it is null or throws an exception. */
-       public static void closeFOQuietly(FileObject fo) {
-               if (fo != null) {
-                       try {
-                               fo.close();
-                       } catch (Exception e) {
-                               // silent
-                       }
-               }
-       }
-       
-       /** Prevents instantiation */
-       private BackupUtils() {
-       }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/MySqlBackup.java
deleted file mode 100644 (file)
index 765c564..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a MySQL database using mysqldump. */
-public class MySqlBackup extends OsCallBackup {
-       private String mysqldumpLocation = "/usr/bin/mysqldump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public MySqlBackup() {
-       }
-
-       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               if (getName() == null)
-                       setName(dbName + ".mysql");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null)
-                       setCommand(mysqldumpLocation
-                                       + " --lock-tables --add-locks --add-drop-table"
-                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setMysqldumpLocation(String mysqldumpLocation) {
-               this.mysqldumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/OpenLdapBackup.java
deleted file mode 100644 (file)
index 96c2f3a..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileObject;
-import org.argeo.cms.CmsException;
-
-/** Backups an OpenLDAP server using slapcat */
-public class OpenLdapBackup extends OsCallBackup {
-       private String slapcatLocation = "/usr/sbin/slapcat";
-       private String slapdConfLocation = "/etc/openldap/slapd.conf";
-       private String baseDn;
-
-       public OpenLdapBackup() {
-               super();
-       }
-
-       public OpenLdapBackup(String baseDn) {
-               super();
-               this.baseDn = baseDn;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (baseDn == null)
-                       throw new CmsException("Base DN must be set");
-
-               if (getCommand() == null)
-                       setCommand(slapcatLocation
-                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
-               getVariables().put("slapdConfLocation", slapdConfLocation);
-               getVariables().put("baseDn", baseDn);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setSlapcatLocation(String slapcatLocation) {
-               this.slapcatLocation = slapcatLocation;
-       }
-
-       public void setSlapdConfLocation(String slapdConfLocation) {
-               this.slapdConfLocation = slapdConfLocation;
-       }
-
-       public void setBaseDn(String baseDn) {
-               this.baseDn = baseDn;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/OsCallBackup.java
deleted file mode 100644 (file)
index ad8ffe8..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.exec.CommandLine;
-import org.apache.commons.exec.DefaultExecutor;
-import org.apache.commons.exec.ExecuteException;
-import org.apache.commons.exec.ExecuteStreamHandler;
-import org.apache.commons.exec.Executor;
-import org.apache.commons.exec.PumpStreamHandler;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileContent;
-import org.apache.commons.vfs2.FileObject;
-import org.argeo.cms.CmsException;
-
-/**
- * Runs an OS command and save its standard output as a file. Typically used for
- * MySQL or OpenLDAP dumps.
- */
-public class OsCallBackup extends AbstractAtomicBackup {
-       private final static Log log = LogFactory.getLog(OsCallBackup.class);
-
-       private String command;
-       private Map<String, String> variables = new HashMap<String, String>();
-       private Executor executor = new DefaultExecutor();
-
-       private Map<String, String> environment = new HashMap<String, String>();
-
-       /** Name of the sudo user, root if "", not sudo if null */
-       private String sudo = null;
-
-       public OsCallBackup() {
-       }
-
-       public OsCallBackup(String name) {
-               super(name);
-       }
-
-       public OsCallBackup(String name, String command) {
-               super(name);
-               this.command = command;
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               String commandToUse = command;
-
-               // sudo
-               if (sudo != null) {
-                       if (sudo.equals(""))
-                               commandToUse = "sudo " + commandToUse;
-                       else
-                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
-               }
-
-               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
-               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
-               if (log.isTraceEnabled())
-                       log.trace(commandLine.toString());
-
-               try {
-                       // stdout
-                       FileContent targetContent = targetFo.getContent();
-                       // stderr
-                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(targetContent.getOutputStream(), errBos);
-                       executor.setStreamHandler(streamHandler);
-                       executor.execute(commandLine, environment);
-               } catch (ExecuteException e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new CmsException("Process " + commandLine + " failed (" + e.getExitValue() + "): " + errStr, e);
-               } catch (Exception e) {
-                       byte[] err = errBos.toByteArray();
-                       String errStr = new String(err);
-                       throw new CmsException("Process " + commandLine + " failed: " + errStr, e);
-               } finally {
-                       IOUtils.closeQuietly(errBos);
-               }
-       }
-
-       public void setCommand(String command) {
-               this.command = command;
-       }
-
-       protected String getCommand() {
-               return command;
-       }
-
-       /**
-        * A reference to the environment variables that will be passed to the
-        * process. Empty by default.
-        */
-       protected Map<String, String> getEnvironment() {
-               return environment;
-       }
-
-       protected Map<String, String> getVariables() {
-               return variables;
-       }
-
-       public void setVariables(Map<String, String> variables) {
-               this.variables = variables;
-       }
-
-       public void setExecutor(Executor executor) {
-               this.executor = executor;
-       }
-
-       public void setSudo(String sudo) {
-               this.sudo = sudo;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/PostgreSqlBackup.java
deleted file mode 100644 (file)
index dbc3624..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a PostgreSQL database using pg_dump. */
-public class PostgreSqlBackup extends OsCallBackup {
-       /**
-        * PostgreSQL password environment variable (see
-        * http://stackoverflow.com/questions
-        * /2893954/how-to-pass-in-password-to-pg-dump)
-        */
-       protected final static String PGPASSWORD = "PGPASSWORD";
-
-       private String pgDumpLocation = "/usr/bin/pg_dump";
-
-       private String dbUser;
-       private String dbPassword;
-       private String dbName;
-
-       public PostgreSqlBackup() {
-               super();
-       }
-
-       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
-               this.dbUser = dbUser;
-               this.dbPassword = dbPassword;
-               this.dbName = dbName;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // disable compression since pg_dump is used with -Fc option
-               setCompression(null);
-
-               if (getName() == null)
-                       setName(dbName + ".pgdump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       getEnvironment().put(PGPASSWORD, dbPassword);
-                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
-               }
-               getVariables().put("dbUser", dbUser);
-               getVariables().put("dbPassword", dbPassword);
-               getVariables().put("dbName", dbName);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setDbUser(String dbUser) {
-               this.dbUser = dbUser;
-       }
-
-       public void setDbPassword(String dbPassword) {
-               this.dbPassword = dbPassword;
-       }
-
-       public void setDbName(String dbName) {
-               this.dbName = dbName;
-       }
-
-       public void setPgDumpLocation(String mysqldumpLocation) {
-               this.pgDumpLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupContext.java
deleted file mode 100644 (file)
index 8e9e418..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import org.apache.commons.vfs2.FileSystemManager;
-
-/** Simple implementation of a backup context */
-public class SimpleBackupContext implements BackupContext {
-       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
-       private final Date timestamp;
-       private final String name;
-
-       private final FileSystemManager fileSystemManager;
-
-       public SimpleBackupContext(FileSystemManager fileSystemManager,
-                       String backupsBase, String name) {
-               this.name = name;
-               this.timestamp = new Date();
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public Date getTimestamp() {
-               return timestamp;
-       }
-
-       public String getTimestampAsString() {
-               return dateFormat.format(timestamp);
-       }
-
-       public String getSystemName() {
-               return name;
-       }
-
-       public String getRelativeFolder() {
-               return name + '/' + getTimestampAsString();
-       }
-
-       public DateFormat getDateFormat() {
-               return dateFormat;
-       }
-
-       public FileSystemManager getFileSystemManager() {
-               return fileSystemManager;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SimpleBackupPurge.java
deleted file mode 100644 (file)
index 33b5b5e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.text.DateFormat;
-import java.time.Period;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Date;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.argeo.cms.CmsException;
-
-/** Simple backup purge which keeps backups only for a given number of days */
-public class SimpleBackupPurge implements BackupPurge {
-       private final static Log log = LogFactory.getLog(SimpleBackupPurge.class);
-
-       private Integer daysKept = 30;
-
-       @Override
-       public void purge(FileSystemManager fileSystemManager, String base, String name, DateFormat dateFormat,
-                       FileSystemOptions opts) {
-               try {
-                       ZonedDateTime nowDt = ZonedDateTime.now();
-                       FileObject baseFo = fileSystemManager.resolveFile(base + '/' + name, opts);
-
-                       SortedMap<ZonedDateTime, FileObject> toDelete = new TreeMap<ZonedDateTime, FileObject>();
-                       int backupCount = 0;
-
-                       // make sure base dir exists
-                       baseFo.createFolder();
-
-                       // scan backups and list those which should be deleted
-                       for (FileObject backupFo : baseFo.getChildren()) {
-                               String backupName = backupFo.getName().getBaseName();
-                               Date backupDate = dateFormat.parse(backupName);
-                               backupCount++;
-                               ZonedDateTime backupDt = ZonedDateTime.ofInstant(backupDate.toInstant(), ZoneId.systemDefault());
-                               Period sinceThen = Period.between(backupDt.toLocalDate(), nowDt.toLocalDate());
-                               // new Period(backupDt, nowDt);
-                               int days = sinceThen.getDays();
-                               // int days = sinceThen.getMinutes();
-                               if (days > daysKept) {
-                                       toDelete.put(backupDt, backupFo);
-                               }
-                       }
-
-                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
-                               // all backups would be deleted
-                               // but we want to keep at least one
-                               ZonedDateTime lastBackupDt = toDelete.firstKey();
-                               FileObject keptFo = toDelete.remove(lastBackupDt);
-                               log.warn("Backup " + keptFo + " kept although it is older than " + daysKept + " days.");
-                       }
-
-                       // delete old backups
-                       for (FileObject backupFo : toDelete.values()) {
-                               backupFo.delete(Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Deleted backup " + backupFo);
-                       }
-               } catch (Exception e) {
-                       throw new CmsException("Could not purge previous backups", e);
-               }
-
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SvnBackup.java
deleted file mode 100644 (file)
index 7367c04..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.io.File;
-
-import org.apache.commons.vfs2.FileObject;
-
-/** Backups a Subversion repository using svnadmin. */
-public class SvnBackup extends OsCallBackup {
-       private String svnadminLocation = "/usr/bin/svnadmin";
-
-       private String repoLocation;
-       private String repoName;
-
-       public SvnBackup() {
-       }
-
-       public SvnBackup(String repoLocation) {
-               this.repoLocation = repoLocation;
-               init();
-       }
-
-       @Override
-       public void init() {
-               // use directory as repo name
-               if (repoName == null)
-                       repoName = new File(repoLocation).getName();
-
-               if (getName() == null)
-                       setName(repoName + ".svndump");
-               super.init();
-       }
-
-       @Override
-       public void writeBackup(FileObject targetFo) {
-               if (getCommand() == null) {
-                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
-               }
-               getVariables().put("repoLocation", repoLocation);
-
-               super.writeBackup(targetFo);
-       }
-
-       public void setRepoLocation(String repoLocation) {
-               this.repoLocation = repoLocation;
-       }
-
-       public void setRepoName(String repoName) {
-               this.repoName = repoName;
-       }
-
-       public void setSvnadminLocation(String mysqldumpLocation) {
-               this.svnadminLocation = mysqldumpLocation;
-       }
-
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java b/org.argeo.cms/src/org/argeo/cms/internal/backup/SystemBackup.java
deleted file mode 100644 (file)
index 36d3e0b..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed 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.argeo.cms.internal.backup;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.vfs2.FileObject;
-import org.apache.commons.vfs2.FileSystemException;
-import org.apache.commons.vfs2.FileSystemManager;
-import org.apache.commons.vfs2.FileSystemOptions;
-import org.apache.commons.vfs2.Selectors;
-import org.apache.commons.vfs2.UserAuthenticator;
-import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
-import org.argeo.cms.CmsException;
-import org.argeo.util.LangUtils;
-
-/**
- * Combines multiple backups and transfer them to a remote location. Purges
- * remote and local data based on certain criteria.
- */
-public class SystemBackup implements Runnable {
-       private final static Log log = LogFactory.getLog(SystemBackup.class);
-
-       private FileSystemManager fileSystemManager;
-       private UserAuthenticator userAuthenticator = null;
-
-       private String backupsBase;
-       private String systemName;
-
-       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-       private BackupPurge backupPurge = new SimpleBackupPurge();
-
-       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
-
-       @Override
-       public void run() {
-               if (atomicBackups.size() == 0)
-                       throw new CmsException("No atomic backup listed");
-               List<String> failures = new ArrayList<String>();
-
-               SimpleBackupContext backupContext = new SimpleBackupContext(fileSystemManager, backupsBase, systemName);
-
-               // purge older backups
-               FileSystemOptions opts = new FileSystemOptions();
-               try {
-                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, userAuthenticator);
-               } catch (FileSystemException e) {
-                       throw new CmsException("Cannot create authentication", e);
-               }
-
-               try {
-
-                       backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts);
-               } catch (Exception e) {
-                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
-                       log.error("Purge of " + backupsBase + " failed", e);
-               }
-
-               // perform backup
-               for (AtomicBackup atomickBackup : atomicBackups) {
-                       try {
-                               String target = atomickBackup.backup(fileSystemManager, backupsBase, backupContext, opts);
-                               if (log.isDebugEnabled())
-                                       log.debug("Performed backup " + target);
-                       } catch (Exception e) {
-                               String msg = "Atomic backup " + atomickBackup.getName() + " failed: "
-                                               + LangUtils.chainCausesMessages(e);
-                               failures.add(msg);
-                               log.error(msg);
-                               if (log.isTraceEnabled())
-                                       log.trace("Stacktrace of atomic backup " + atomickBackup.getName() + " failure.", e);
-                       }
-               }
-
-               // dispatch to remote
-               for (String remoteBase : remoteBases.keySet()) {
-                       FileObject localBaseFo = null;
-                       FileObject remoteBaseFo = null;
-                       UserAuthenticator auth = remoteBases.get(remoteBase);
-
-                       // authentication
-                       FileSystemOptions remoteOpts = new FileSystemOptions();
-                       try {
-                               DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(remoteOpts, auth);
-                               backupPurge.purge(fileSystemManager, remoteBase, systemName, backupContext.getDateFormat(), remoteOpts);
-                       } catch (Exception e) {
-                               failures.add("Purge " + remoteBase + " failed: " + e.getMessage());
-                               log.error("Cannot purge " + remoteBase, e);
-                       }
-
-                       try {
-                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/' + backupContext.getRelativeFolder(),
-                                               opts);
-                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/' + backupContext.getRelativeFolder(),
-                                               remoteOpts);
-                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
-                               if (log.isDebugEnabled())
-                                       log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo);
-                               // }
-                       } catch (Exception e) {
-                               failures.add("Dispatch to " + remoteBase + " failed: " + e.getMessage());
-                               log.error("Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " + remoteBase, e);
-                       }
-                       BackupUtils.closeFOQuietly(localBaseFo);
-                       BackupUtils.closeFOQuietly(remoteBaseFo);
-               }
-
-               int failureCount = 0;
-               if (failures.size() > 0) {
-                       StringBuffer buf = new StringBuffer();
-                       for (String failure : failures) {
-                               buf.append('\n').append(failureCount).append(" - ").append(failure);
-                               failureCount++;
-                       }
-                       throw new CmsException(failureCount + " error(s) when running the backup,"
-                                       + " check the logs and the backups as soon as possible." + buf);
-               }
-       }
-
-       public void setFileSystemManager(FileSystemManager fileSystemManager) {
-               this.fileSystemManager = fileSystemManager;
-       }
-
-       public void setBackupsBase(String backupsBase) {
-               this.backupsBase = backupsBase;
-       }
-
-       public void setSystemName(String name) {
-               this.systemName = name;
-       }
-
-       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
-               this.atomicBackups = atomicBackups;
-       }
-
-       public void setBackupPurge(BackupPurge backupPurge) {
-               this.backupPurge = backupPurge;
-       }
-
-       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
-               this.userAuthenticator = userAuthenticator;
-       }
-
-       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
-               this.remoteBases = remoteBases;
-       }
-
-       // public static void main(String args[]) {
-       // while (true) {
-       // try {
-       // StandardFileSystemManager fsm = new StandardFileSystemManager();
-       // fsm.init();
-       //
-       // SystemBackup systemBackup = new SystemBackup();
-       // systemBackup.setSystemName("mySystem");
-       // systemBackup
-       // .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
-       // systemBackup.setFileSystemManager(fsm);
-       //
-       // List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
-       //
-       // MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
-       // atomicBackups.add(mySqlBackup);
-       // PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
-       // "argeo", "argeo", "gis_template");
-       // atomicBackups.add(postgreSqlBackup);
-       // SvnBackup svnBackup = new SvnBackup(
-       // "/home/mbaudier/tmp/testsvnrepo");
-       // atomicBackups.add(svnBackup);
-       //
-       // systemBackup.setAtomicBackups(atomicBackups);
-       //
-       // Map<String, UserAuthenticator> remoteBases = new HashMap<String,
-       // UserAuthenticator>();
-       // StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
-       // null, "demo", "demo");
-       // remoteBases.put("sftp://localhost/home/mbaudier/test",
-       // userAuthenticator);
-       // systemBackup.setRemoteBases(remoteBases);
-       //
-       // systemBackup.run();
-       //
-       // fsm.close();
-       // } catch (FileSystemException e) {
-       // // TODO Auto-generated catch block
-       // e.printStackTrace();
-       // System.exit(1);
-       // }
-       //
-       // // wait
-       // try {
-       // Thread.sleep(120 * 1000);
-       // } catch (InterruptedException e) {
-       // e.printStackTrace();
-       // }
-       // }
-       // }
-}
diff --git a/org.argeo.cms/src/org/argeo/cms/internal/http/HttpConstants.java b/org.argeo.cms/src/org/argeo/cms/internal/http/HttpConstants.java
new file mode 100644 (file)
index 0000000..5fe57b7
--- /dev/null
@@ -0,0 +1,21 @@
+package org.argeo.cms.internal.http;
+
+/** Compatible with Jetty. */
+public interface HttpConstants {
+       public static final String HTTP_ENABLED = "http.enabled";
+       public static final String HTTP_PORT = "http.port";
+       public static final String HTTP_HOST = "http.host";
+       public static final String HTTPS_ENABLED = "https.enabled";
+       public static final String HTTPS_HOST = "https.host";
+       public static final String HTTPS_PORT = "https.port";
+       public static final String SSL_KEYSTORE = "ssl.keystore";
+       public static final String SSL_PASSWORD = "ssl.password";
+       public static final String SSL_KEYPASSWORD = "ssl.keypassword";
+       public static final String SSL_NEEDCLIENTAUTH = "ssl.needclientauth";
+       public static final String SSL_WANTCLIENTAUTH = "ssl.wantclientauth";
+       public static final String SSL_PROTOCOL = "ssl.protocol";
+       public static final String SSL_ALGORITHM = "ssl.algorithm";
+       public static final String SSL_KEYSTORETYPE = "ssl.keystoretype";
+       public static final String JETTY_PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty.";
+
+}
index 6175e4d030c79abe9d99d7eaec0561391f1677fa..98c2483cca13f4490caacea4019de2dfd223583c 100644 (file)
@@ -22,10 +22,10 @@ import org.apache.commons.io.FileUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.internal.http.HttpConstants;
 import org.argeo.cms.internal.jcr.RepoConf;
 import org.argeo.node.NodeConstants;
 import org.argeo.osgi.useradmin.UserAdminConf;
-import org.eclipse.equinox.http.jetty.JettyConstants;
 
 /**
  * Interprets framework properties in order to generate the initial deploy
@@ -56,35 +56,35 @@ class FirstInit {
                String httpPort = getFrameworkProp("org.osgi.service.http.port");
                String httpsPort = getFrameworkProp("org.osgi.service.http.port.secure");
                /// TODO make it more generic
-               String httpHost = getFrameworkProp(JettyConstants.PROPERTY_PREFIX + JettyConstants.HTTP_HOST);
-               String httpsHost = getFrameworkProp(JettyConstants.PROPERTY_PREFIX + JettyConstants.HTTPS_HOST);
+               String httpHost = getFrameworkProp(HttpConstants.JETTY_PROPERTY_PREFIX + HttpConstants.HTTP_HOST);
+               String httpsHost = getFrameworkProp(HttpConstants.JETTY_PROPERTY_PREFIX + HttpConstants.HTTPS_HOST);
 
                final Hashtable<String, Object> props = new Hashtable<String, Object>();
                // try {
                if (httpPort != null || httpsPort != null) {
                        if (httpPort != null) {
-                               props.put(JettyConstants.HTTP_PORT, httpPort);
-                               props.put(JettyConstants.HTTP_ENABLED, true);
+                               props.put(HttpConstants.HTTP_PORT, httpPort);
+                               props.put(HttpConstants.HTTP_ENABLED, true);
                        }
                        if (httpsPort != null) {
-                               props.put(JettyConstants.HTTPS_PORT, httpsPort);
-                               props.put(JettyConstants.HTTPS_ENABLED, true);
+                               props.put(HttpConstants.HTTPS_PORT, httpsPort);
+                               props.put(HttpConstants.HTTPS_ENABLED, true);
                                Path keyStorePath = KernelUtils.getOsgiInstancePath(KernelConstants.DEFAULT_KEYSTORE_PATH);
                                String keyStorePassword = getFrameworkProp(
-                                               JettyConstants.PROPERTY_PREFIX + JettyConstants.SSL_PASSWORD);
+                                               HttpConstants.JETTY_PROPERTY_PREFIX + HttpConstants.SSL_PASSWORD);
                                if (keyStorePassword == null)
                                        keyStorePassword = "changeit";
                                if (!Files.exists(keyStorePath))
                                        createSelfSignedKeyStore(keyStorePath, keyStorePassword);
-                               props.put(JettyConstants.SSL_KEYSTORETYPE, "PKCS12");
-                               props.put(JettyConstants.SSL_KEYSTORE, keyStorePath.toString());
-                               props.put(JettyConstants.SSL_PASSWORD, keyStorePassword);
-                               props.put(JettyConstants.SSL_WANTCLIENTAUTH, true);
+                               props.put(HttpConstants.SSL_KEYSTORETYPE, "PKCS12");
+                               props.put(HttpConstants.SSL_KEYSTORE, keyStorePath.toString());
+                               props.put(HttpConstants.SSL_PASSWORD, keyStorePassword);
+                               props.put(HttpConstants.SSL_WANTCLIENTAUTH, true);
                        }
                        if (httpHost != null)
-                               props.put(JettyConstants.HTTP_HOST, httpHost);
+                               props.put(HttpConstants.HTTP_HOST, httpHost);
                        if (httpsHost != null)
-                               props.put(JettyConstants.HTTPS_HOST, httpHost);
+                               props.put(HttpConstants.HTTPS_HOST, httpHost);
 
                        props.put(NodeConstants.CN, NodeConstants.DEFAULT);
                }
index 45f3354b89b55497885878d97f47d2ca37859af4..f8bce9cf689e967620f4be3e894954a2af7d25c0 100644 (file)
@@ -28,6 +28,9 @@ public interface KernelConstants {
        String DEFAULT_USERS_BASE_PATH = "/users";
        String DEFAULT_GROUPS_BASE_PATH = "/groups";
 
+       // HTTP client
+       String COOKIE_POLICY_BROWSER_COMPATIBILITY = "compatibility";
+
        // RWT / RAP
        // String PATH_WORKBENCH = "/ui";
        // String PATH_WORKBENCH_PUBLIC = PATH_WORKBENCH + "/public";
index f1132a64260a1ebca5d9e41011aa79ff195442f4..236585e1bd2ca1fb313c48e88f392aaf2c0f1ab8 100644 (file)
@@ -29,7 +29,6 @@ import javax.transaction.TransactionManager;
 
 import org.apache.commons.httpclient.auth.AuthPolicy;
 import org.apache.commons.httpclient.auth.CredentialsProvider;
-import org.apache.commons.httpclient.cookie.CookiePolicy;
 import org.apache.commons.httpclient.params.DefaultHttpParams;
 import org.apache.commons.httpclient.params.HttpMethodParams;
 import org.apache.commons.httpclient.params.HttpParams;
@@ -162,14 +161,12 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
        public String getName() {
                return "Node User Admin";
        }
-       
-       
 
        @Override
        protected void addAbstractSystemRoles(Authorization rawAuthorization, Set<String> sysRoles) {
-               if(rawAuthorization.getName()==null) {
+               if (rawAuthorization.getName() == null) {
                        sysRoles.add(NodeConstants.ROLE_ANONYMOUS);
-               }else {
+               } else {
                        sysRoles.add(NodeConstants.ROLE_USER);
                }
        }
@@ -215,7 +212,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor
                        // schemes.add(AuthPolicy.BASIC);// incompatible with Basic
                        params.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, schemes);
                        params.setParameter(CredentialsProvider.PROVIDER, new HttpCredentialProvider());
-                       params.setParameter(HttpMethodParams.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
+                       params.setParameter(HttpMethodParams.COOKIE_POLICY, KernelConstants.COOKIE_POLICY_BROWSER_COMPATIBILITY);
                        // params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
                }
        }
diff --git a/org.argeo.maintenance/.classpath b/org.argeo.maintenance/.classpath
new file mode 100644 (file)
index 0000000..eca7bdb
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.argeo.maintenance/.gitignore b/org.argeo.maintenance/.gitignore
new file mode 100644 (file)
index 0000000..09e3bc9
--- /dev/null
@@ -0,0 +1,2 @@
+/bin/
+/target/
diff --git a/org.argeo.maintenance/.project b/org.argeo.maintenance/.project
new file mode 100644 (file)
index 0000000..d1c87c7
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.maintenance</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/org.argeo.maintenance/META-INF/.gitignore b/org.argeo.maintenance/META-INF/.gitignore
new file mode 100644 (file)
index 0000000..4854a41
--- /dev/null
@@ -0,0 +1 @@
+/MANIFEST.MF
diff --git a/org.argeo.maintenance/bnd.bnd b/org.argeo.maintenance/bnd.bnd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/org.argeo.maintenance/build.properties b/org.argeo.maintenance/build.properties
new file mode 100644 (file)
index 0000000..34d2e4d
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/org.argeo.maintenance/pom.xml b/org.argeo.maintenance/pom.xml
new file mode 100644 (file)
index 0000000..8c4abf3
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+       <modelVersion>4.0.0</modelVersion>
+       <parent>
+               <groupId>org.argeo.commons</groupId>
+               <artifactId>argeo-commons</artifactId>
+               <version>2.1.71-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.maintenance</artifactId>
+       <name>Maintenance</name>
+       <packaging>jar</packaging>
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.jcr</artifactId>
+                       <version>2.1.71-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.enterprise</artifactId>
+                       <version>2.1.71-SNAPSHOT</version>
+               </dependency>
+       </dependencies>
+</project>
\ No newline at end of file
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/MaintenanceException.java b/org.argeo.maintenance/src/org/argeo/maintenance/MaintenanceException.java
new file mode 100644 (file)
index 0000000..dc4243e
--- /dev/null
@@ -0,0 +1,13 @@
+package org.argeo.maintenance;
+
+public class MaintenanceException extends RuntimeException {
+       private static final long serialVersionUID = -4571088120514827735L;
+
+       public MaintenanceException(String message) {
+               super(message);
+       }
+
+       public MaintenanceException(String message, Throwable cause) {
+               super(message, cause);
+       }
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AbstractAtomicBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AbstractAtomicBackup.java
new file mode 100644 (file)
index 0000000..ae587ea
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;
+import org.argeo.maintenance.MaintenanceException;
+
+/**
+ * Simplify atomic backups implementation, especially by managing VFS.
+ */
+public abstract class AbstractAtomicBackup implements AtomicBackup {
+       private String name;
+       private String compression = "bz2";
+
+       protected abstract void writeBackup(FileObject targetFo);
+
+       public AbstractAtomicBackup() {
+       }
+
+       public AbstractAtomicBackup(String name) {
+               this.name = name;
+       }
+
+       public void init() {
+               if (name == null)
+                       throw new MaintenanceException("Atomic backup name must be set");
+       }
+
+       public void destroy() {
+
+       }
+
+       @Override
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts) {
+               if (name == null)
+                       throw new MaintenanceException("Atomic backup name must be set");
+
+               FileObject targetFo = null;
+               try {
+                       if (backupsBase.startsWith("sftp:"))
+                               SftpFileSystemConfigBuilder.getInstance()
+                                               .setStrictHostKeyChecking(opts, "no");
+                       if (compression == null || compression.equals("none"))
+                               targetFo = fileSystemManager.resolveFile(backupsBase + '/'
+                                               + backupContext.getRelativeFolder() + '/' + name, opts);
+                       else if (compression.equals("bz2"))
+                               targetFo = fileSystemManager.resolveFile("bz2:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".bz2" + "!" + name, opts);
+                       else if (compression.equals("gz"))
+                               targetFo = fileSystemManager.resolveFile("gz:" + backupsBase
+                                               + '/' + backupContext.getRelativeFolder() + '/' + name
+                                               + ".gz" + "!" + name, opts);
+                       else
+                               throw new MaintenanceException("Unsupported compression "
+                                               + compression);
+
+                       writeBackup(targetFo);
+
+                       return targetFo.toString();
+               } catch (Exception e) {
+                       throw new MaintenanceException("Cannot backup " + name + " to "
+                                       + targetFo, e);
+               } finally {
+                       BackupUtils.closeFOQuietly(targetFo);
+               }
+       }
+
+       public void setName(String name) {
+               this.name = name;
+       }
+
+       public String getName() {
+               return name;
+       }
+
+       public void setCompression(String compression) {
+               this.compression = compression;
+       }
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AtomicBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/AtomicBackup.java
new file mode 100644 (file)
index 0000000..e8c3ded
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Performs the backup of a single component, typically a database dump */
+public interface AtomicBackup {
+       /** Name identifiying this backup */
+       public String getName();
+
+       /**
+        * Retrieves the data of the component in a format that allows to restore
+        * the component
+        * 
+        * @param backupContext
+        *            the context of this backup
+        * @return the VFS URI of the generated file or directory
+        */
+       public String backup(FileSystemManager fileSystemManager,
+                       String backupsBase, BackupContext backupContext,
+                       FileSystemOptions opts);
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupContext.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupContext.java
new file mode 100644 (file)
index 0000000..cc1391f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+/**
+ * Transient information of a given backup, centralizing common information such
+ * as timestamp and location.
+ */
+public interface BackupContext {
+       /** Backup date */
+       public Date getTimestamp();
+
+       /** Formatted backup date */
+       public String getTimestampAsString();
+
+       /** System name */
+       public String getSystemName();
+
+       /** Local base */
+       public String getRelativeFolder();
+
+       /** Date format */
+       public DateFormat getDateFormat();
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupFileSystemManager.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupFileSystemManager.java
new file mode 100644 (file)
index 0000000..3053f0a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs2.provider.bzip2.Bzip2FileProvider;
+import org.apache.commons.vfs2.provider.ftp.FtpFileProvider;
+import org.apache.commons.vfs2.provider.gzip.GzipFileProvider;
+import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
+import org.apache.commons.vfs2.provider.ram.RamFileProvider;
+import org.apache.commons.vfs2.provider.sftp.SftpFileProvider;
+import org.apache.commons.vfs2.provider.url.UrlFileProvider;
+import org.argeo.maintenance.MaintenanceException;
+
+/**
+ * Programatically configured VFS file system manager which can be declared as a
+ * bean and associated with a life cycle (methods
+ * {@link DefaultFileSystemManager#init()} and
+ * {@link DefaultFileSystemManager#close()}). Supports bz2, file, ram, gzip,
+ * ftp, sftp
+ */
+public class BackupFileSystemManager extends DefaultFileSystemManager {
+
+       public BackupFileSystemManager() {
+               super();
+               try {
+                       addProvider("file", new DefaultLocalFileProvider());
+                       addProvider("bz2", new Bzip2FileProvider());
+                       addProvider("ftp", new FtpFileProvider());
+                       addProvider("sftp", new SftpFileProvider());
+                       addProvider("gzip", new GzipFileProvider());
+                       addProvider("ram", new RamFileProvider());
+                       setDefaultProvider(new UrlFileProvider());
+               } catch (FileSystemException e) {
+                       throw new MaintenanceException("Cannot configure backup file provider", e);
+               }
+       }
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupPurge.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupPurge.java
new file mode 100644 (file)
index 0000000..face8a1
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.text.DateFormat;
+
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+
+/** Purges previous backups */
+public interface BackupPurge {
+       /**
+        * Purge the backups identified by these arguments. Although these are the
+        * same fields as a {@link BackupContext} we don't pass it as argument since
+        * we want to use this interface to purge remote backups as well (that is,
+        * with a different base), or outside the scope of a running backup.
+        */
+       public void purge(FileSystemManager fileSystemManager, String base,
+                       String name, DateFormat dateFormat, FileSystemOptions opts);
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupUtils.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/BackupUtils.java
new file mode 100644 (file)
index 0000000..94e8a1d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backup utilities */
+public class BackupUtils {
+       /** Close a file object quietly even if it is null or throws an exception. */
+       public static void closeFOQuietly(FileObject fo) {
+               if (fo != null) {
+                       try {
+                               fo.close();
+                       } catch (Exception e) {
+                               // silent
+                       }
+               }
+       }
+       
+       /** Prevents instantiation */
+       private BackupUtils() {
+       }
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/MySqlBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/MySqlBackup.java
new file mode 100644 (file)
index 0000000..7ab2d6a
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a MySQL database using mysqldump. */
+public class MySqlBackup extends OsCallBackup {
+       private String mysqldumpLocation = "/usr/bin/mysqldump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public MySqlBackup() {
+       }
+
+       public MySqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               if (getName() == null)
+                       setName(dbName + ".mysql");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null)
+                       setCommand(mysqldumpLocation
+                                       + " --lock-tables --add-locks --add-drop-table"
+                                       + " -u ${dbUser} --password=${dbPassword} --databases ${dbName}");
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setMysqldumpLocation(String mysqldumpLocation) {
+               this.mysqldumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OpenLdapBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OpenLdapBackup.java
new file mode 100644 (file)
index 0000000..415bc24
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+import org.argeo.maintenance.MaintenanceException;
+
+/** Backups an OpenLDAP server using slapcat */
+public class OpenLdapBackup extends OsCallBackup {
+       private String slapcatLocation = "/usr/sbin/slapcat";
+       private String slapdConfLocation = "/etc/openldap/slapd.conf";
+       private String baseDn;
+
+       public OpenLdapBackup() {
+               super();
+       }
+
+       public OpenLdapBackup(String baseDn) {
+               super();
+               this.baseDn = baseDn;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (baseDn == null)
+                       throw new MaintenanceException("Base DN must be set");
+
+               if (getCommand() == null)
+                       setCommand(slapcatLocation
+                                       + " -f ${slapdConfLocation} -b '${baseDn}'");
+               getVariables().put("slapdConfLocation", slapdConfLocation);
+               getVariables().put("baseDn", baseDn);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setSlapcatLocation(String slapcatLocation) {
+               this.slapcatLocation = slapcatLocation;
+       }
+
+       public void setSlapdConfLocation(String slapdConfLocation) {
+               this.slapdConfLocation = slapdConfLocation;
+       }
+
+       public void setBaseDn(String baseDn) {
+               this.baseDn = baseDn;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OsCallBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/OsCallBackup.java
new file mode 100644 (file)
index 0000000..07589d3
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.exec.CommandLine;
+import org.apache.commons.exec.DefaultExecutor;
+import org.apache.commons.exec.ExecuteException;
+import org.apache.commons.exec.ExecuteStreamHandler;
+import org.apache.commons.exec.Executor;
+import org.apache.commons.exec.PumpStreamHandler;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileObject;
+import org.argeo.maintenance.MaintenanceException;
+
+/**
+ * Runs an OS command and save its standard output as a file. Typically used for
+ * MySQL or OpenLDAP dumps.
+ */
+public class OsCallBackup extends AbstractAtomicBackup {
+       private final static Log log = LogFactory.getLog(OsCallBackup.class);
+
+       private String command;
+       private Map<String, String> variables = new HashMap<String, String>();
+       private Executor executor = new DefaultExecutor();
+
+       private Map<String, String> environment = new HashMap<String, String>();
+
+       /** Name of the sudo user, root if "", not sudo if null */
+       private String sudo = null;
+
+       public OsCallBackup() {
+       }
+
+       public OsCallBackup(String name) {
+               super(name);
+       }
+
+       public OsCallBackup(String name, String command) {
+               super(name);
+               this.command = command;
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               String commandToUse = command;
+
+               // sudo
+               if (sudo != null) {
+                       if (sudo.equals(""))
+                               commandToUse = "sudo " + commandToUse;
+                       else
+                               commandToUse = "sudo -u " + sudo + " " + commandToUse;
+               }
+
+               CommandLine commandLine = CommandLine.parse(commandToUse, variables);
+               ByteArrayOutputStream errBos = new ByteArrayOutputStream();
+               if (log.isTraceEnabled())
+                       log.trace(commandLine.toString());
+
+               try {
+                       // stdout
+                       FileContent targetContent = targetFo.getContent();
+                       // stderr
+                       ExecuteStreamHandler streamHandler = new PumpStreamHandler(targetContent.getOutputStream(), errBos);
+                       executor.setStreamHandler(streamHandler);
+                       executor.execute(commandLine, environment);
+               } catch (ExecuteException e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new MaintenanceException("Process " + commandLine + " failed (" + e.getExitValue() + "): " + errStr, e);
+               } catch (Exception e) {
+                       byte[] err = errBos.toByteArray();
+                       String errStr = new String(err);
+                       throw new MaintenanceException("Process " + commandLine + " failed: " + errStr, e);
+               } finally {
+                       IOUtils.closeQuietly(errBos);
+               }
+       }
+
+       public void setCommand(String command) {
+               this.command = command;
+       }
+
+       protected String getCommand() {
+               return command;
+       }
+
+       /**
+        * A reference to the environment variables that will be passed to the
+        * process. Empty by default.
+        */
+       protected Map<String, String> getEnvironment() {
+               return environment;
+       }
+
+       protected Map<String, String> getVariables() {
+               return variables;
+       }
+
+       public void setVariables(Map<String, String> variables) {
+               this.variables = variables;
+       }
+
+       public void setExecutor(Executor executor) {
+               this.executor = executor;
+       }
+
+       public void setSudo(String sudo) {
+               this.sudo = sudo;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/PostgreSqlBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/PostgreSqlBackup.java
new file mode 100644 (file)
index 0000000..da3ea38
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a PostgreSQL database using pg_dump. */
+public class PostgreSqlBackup extends OsCallBackup {
+       /**
+        * PostgreSQL password environment variable (see
+        * http://stackoverflow.com/questions
+        * /2893954/how-to-pass-in-password-to-pg-dump)
+        */
+       protected final static String PGPASSWORD = "PGPASSWORD";
+
+       private String pgDumpLocation = "/usr/bin/pg_dump";
+
+       private String dbUser;
+       private String dbPassword;
+       private String dbName;
+
+       public PostgreSqlBackup() {
+               super();
+       }
+
+       public PostgreSqlBackup(String dbUser, String dbPassword, String dbName) {
+               this.dbUser = dbUser;
+               this.dbPassword = dbPassword;
+               this.dbName = dbName;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // disable compression since pg_dump is used with -Fc option
+               setCompression(null);
+
+               if (getName() == null)
+                       setName(dbName + ".pgdump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       getEnvironment().put(PGPASSWORD, dbPassword);
+                       setCommand(pgDumpLocation + " -Fc" + " -U ${dbUser} ${dbName}");
+               }
+               getVariables().put("dbUser", dbUser);
+               getVariables().put("dbPassword", dbPassword);
+               getVariables().put("dbName", dbName);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setDbUser(String dbUser) {
+               this.dbUser = dbUser;
+       }
+
+       public void setDbPassword(String dbPassword) {
+               this.dbPassword = dbPassword;
+       }
+
+       public void setDbName(String dbName) {
+               this.dbName = dbName;
+       }
+
+       public void setPgDumpLocation(String mysqldumpLocation) {
+               this.pgDumpLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupContext.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupContext.java
new file mode 100644 (file)
index 0000000..bef6f65
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.vfs2.FileSystemManager;
+
+/** Simple implementation of a backup context */
+public class SimpleBackupContext implements BackupContext {
+       private DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmm");
+       private final Date timestamp;
+       private final String name;
+
+       private final FileSystemManager fileSystemManager;
+
+       public SimpleBackupContext(FileSystemManager fileSystemManager,
+                       String backupsBase, String name) {
+               this.name = name;
+               this.timestamp = new Date();
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public Date getTimestamp() {
+               return timestamp;
+       }
+
+       public String getTimestampAsString() {
+               return dateFormat.format(timestamp);
+       }
+
+       public String getSystemName() {
+               return name;
+       }
+
+       public String getRelativeFolder() {
+               return name + '/' + getTimestampAsString();
+       }
+
+       public DateFormat getDateFormat() {
+               return dateFormat;
+       }
+
+       public FileSystemManager getFileSystemManager() {
+               return fileSystemManager;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupPurge.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SimpleBackupPurge.java
new file mode 100644 (file)
index 0000000..042070f
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.text.DateFormat;
+import java.time.Period;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.argeo.maintenance.MaintenanceException;
+
+/** Simple backup purge which keeps backups only for a given number of days */
+public class SimpleBackupPurge implements BackupPurge {
+       private final static Log log = LogFactory.getLog(SimpleBackupPurge.class);
+
+       private Integer daysKept = 30;
+
+       @Override
+       public void purge(FileSystemManager fileSystemManager, String base, String name, DateFormat dateFormat,
+                       FileSystemOptions opts) {
+               try {
+                       ZonedDateTime nowDt = ZonedDateTime.now();
+                       FileObject baseFo = fileSystemManager.resolveFile(base + '/' + name, opts);
+
+                       SortedMap<ZonedDateTime, FileObject> toDelete = new TreeMap<ZonedDateTime, FileObject>();
+                       int backupCount = 0;
+
+                       // make sure base dir exists
+                       baseFo.createFolder();
+
+                       // scan backups and list those which should be deleted
+                       for (FileObject backupFo : baseFo.getChildren()) {
+                               String backupName = backupFo.getName().getBaseName();
+                               Date backupDate = dateFormat.parse(backupName);
+                               backupCount++;
+                               ZonedDateTime backupDt = ZonedDateTime.ofInstant(backupDate.toInstant(), ZoneId.systemDefault());
+                               Period sinceThen = Period.between(backupDt.toLocalDate(), nowDt.toLocalDate());
+                               // new Period(backupDt, nowDt);
+                               int days = sinceThen.getDays();
+                               // int days = sinceThen.getMinutes();
+                               if (days > daysKept) {
+                                       toDelete.put(backupDt, backupFo);
+                               }
+                       }
+
+                       if (toDelete.size() != 0 && toDelete.size() == backupCount) {
+                               // all backups would be deleted
+                               // but we want to keep at least one
+                               ZonedDateTime lastBackupDt = toDelete.firstKey();
+                               FileObject keptFo = toDelete.remove(lastBackupDt);
+                               log.warn("Backup " + keptFo + " kept although it is older than " + daysKept + " days.");
+                       }
+
+                       // delete old backups
+                       for (FileObject backupFo : toDelete.values()) {
+                               backupFo.delete(Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Deleted backup " + backupFo);
+                       }
+               } catch (Exception e) {
+                       throw new MaintenanceException("Could not purge previous backups", e);
+               }
+
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SvnBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SvnBackup.java
new file mode 100644 (file)
index 0000000..b725a3e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileObject;
+
+/** Backups a Subversion repository using svnadmin. */
+public class SvnBackup extends OsCallBackup {
+       private String svnadminLocation = "/usr/bin/svnadmin";
+
+       private String repoLocation;
+       private String repoName;
+
+       public SvnBackup() {
+       }
+
+       public SvnBackup(String repoLocation) {
+               this.repoLocation = repoLocation;
+               init();
+       }
+
+       @Override
+       public void init() {
+               // use directory as repo name
+               if (repoName == null)
+                       repoName = new File(repoLocation).getName();
+
+               if (getName() == null)
+                       setName(repoName + ".svndump");
+               super.init();
+       }
+
+       @Override
+       public void writeBackup(FileObject targetFo) {
+               if (getCommand() == null) {
+                       setCommand(svnadminLocation + " dump " + " ${repoLocation}");
+               }
+               getVariables().put("repoLocation", repoLocation);
+
+               super.writeBackup(targetFo);
+       }
+
+       public void setRepoLocation(String repoLocation) {
+               this.repoLocation = repoLocation;
+       }
+
+       public void setRepoName(String repoName) {
+               this.repoName = repoName;
+       }
+
+       public void setSvnadminLocation(String mysqldumpLocation) {
+               this.svnadminLocation = mysqldumpLocation;
+       }
+
+}
diff --git a/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SystemBackup.java b/org.argeo.maintenance/src/org/argeo/maintenance/backup/vfs/SystemBackup.java
new file mode 100644 (file)
index 0000000..480f6dc
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed 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.argeo.maintenance.backup.vfs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.FileSystemOptions;
+import org.apache.commons.vfs2.Selectors;
+import org.apache.commons.vfs2.UserAuthenticator;
+import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
+import org.argeo.maintenance.MaintenanceException;
+import org.argeo.util.LangUtils;
+
+/**
+ * Combines multiple backups and transfer them to a remote location. Purges
+ * remote and local data based on certain criteria.
+ */
+public class SystemBackup implements Runnable {
+       private final static Log log = LogFactory.getLog(SystemBackup.class);
+
+       private FileSystemManager fileSystemManager;
+       private UserAuthenticator userAuthenticator = null;
+
+       private String backupsBase;
+       private String systemName;
+
+       private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+       private BackupPurge backupPurge = new SimpleBackupPurge();
+
+       private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
+
+       @Override
+       public void run() {
+               if (atomicBackups.size() == 0)
+                       throw new MaintenanceException("No atomic backup listed");
+               List<String> failures = new ArrayList<String>();
+
+               SimpleBackupContext backupContext = new SimpleBackupContext(fileSystemManager, backupsBase, systemName);
+
+               // purge older backups
+               FileSystemOptions opts = new FileSystemOptions();
+               try {
+                       DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, userAuthenticator);
+               } catch (FileSystemException e) {
+                       throw new MaintenanceException("Cannot create authentication", e);
+               }
+
+               try {
+
+                       backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts);
+               } catch (Exception e) {
+                       failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
+                       log.error("Purge of " + backupsBase + " failed", e);
+               }
+
+               // perform backup
+               for (AtomicBackup atomickBackup : atomicBackups) {
+                       try {
+                               String target = atomickBackup.backup(fileSystemManager, backupsBase, backupContext, opts);
+                               if (log.isDebugEnabled())
+                                       log.debug("Performed backup " + target);
+                       } catch (Exception e) {
+                               String msg = "Atomic backup " + atomickBackup.getName() + " failed: "
+                                               + LangUtils.chainCausesMessages(e);
+                               failures.add(msg);
+                               log.error(msg);
+                               if (log.isTraceEnabled())
+                                       log.trace("Stacktrace of atomic backup " + atomickBackup.getName() + " failure.", e);
+                       }
+               }
+
+               // dispatch to remote
+               for (String remoteBase : remoteBases.keySet()) {
+                       FileObject localBaseFo = null;
+                       FileObject remoteBaseFo = null;
+                       UserAuthenticator auth = remoteBases.get(remoteBase);
+
+                       // authentication
+                       FileSystemOptions remoteOpts = new FileSystemOptions();
+                       try {
+                               DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(remoteOpts, auth);
+                               backupPurge.purge(fileSystemManager, remoteBase, systemName, backupContext.getDateFormat(), remoteOpts);
+                       } catch (Exception e) {
+                               failures.add("Purge " + remoteBase + " failed: " + e.getMessage());
+                               log.error("Cannot purge " + remoteBase, e);
+                       }
+
+                       try {
+                               localBaseFo = fileSystemManager.resolveFile(backupsBase + '/' + backupContext.getRelativeFolder(),
+                                               opts);
+                               remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/' + backupContext.getRelativeFolder(),
+                                               remoteOpts);
+                               remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
+                               if (log.isDebugEnabled())
+                                       log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo);
+                               // }
+                       } catch (Exception e) {
+                               failures.add("Dispatch to " + remoteBase + " failed: " + e.getMessage());
+                               log.error("Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " + remoteBase, e);
+                       }
+                       BackupUtils.closeFOQuietly(localBaseFo);
+                       BackupUtils.closeFOQuietly(remoteBaseFo);
+               }
+
+               int failureCount = 0;
+               if (failures.size() > 0) {
+                       StringBuffer buf = new StringBuffer();
+                       for (String failure : failures) {
+                               buf.append('\n').append(failureCount).append(" - ").append(failure);
+                               failureCount++;
+                       }
+                       throw new MaintenanceException(failureCount + " error(s) when running the backup,"
+                                       + " check the logs and the backups as soon as possible." + buf);
+               }
+       }
+
+       public void setFileSystemManager(FileSystemManager fileSystemManager) {
+               this.fileSystemManager = fileSystemManager;
+       }
+
+       public void setBackupsBase(String backupsBase) {
+               this.backupsBase = backupsBase;
+       }
+
+       public void setSystemName(String name) {
+               this.systemName = name;
+       }
+
+       public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
+               this.atomicBackups = atomicBackups;
+       }
+
+       public void setBackupPurge(BackupPurge backupPurge) {
+               this.backupPurge = backupPurge;
+       }
+
+       public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
+               this.userAuthenticator = userAuthenticator;
+       }
+
+       public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
+               this.remoteBases = remoteBases;
+       }
+
+       // public static void main(String args[]) {
+       // while (true) {
+       // try {
+       // StandardFileSystemManager fsm = new StandardFileSystemManager();
+       // fsm.init();
+       //
+       // SystemBackup systemBackup = new SystemBackup();
+       // systemBackup.setSystemName("mySystem");
+       // systemBackup
+       // .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
+       // systemBackup.setFileSystemManager(fsm);
+       //
+       // List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
+       //
+       // MySqlBackup mySqlBackup = new MySqlBackup("root", "", "test");
+       // atomicBackups.add(mySqlBackup);
+       // PostgreSqlBackup postgreSqlBackup = new PostgreSqlBackup(
+       // "argeo", "argeo", "gis_template");
+       // atomicBackups.add(postgreSqlBackup);
+       // SvnBackup svnBackup = new SvnBackup(
+       // "/home/mbaudier/tmp/testsvnrepo");
+       // atomicBackups.add(svnBackup);
+       //
+       // systemBackup.setAtomicBackups(atomicBackups);
+       //
+       // Map<String, UserAuthenticator> remoteBases = new HashMap<String,
+       // UserAuthenticator>();
+       // StaticUserAuthenticator userAuthenticator = new StaticUserAuthenticator(
+       // null, "demo", "demo");
+       // remoteBases.put("sftp://localhost/home/mbaudier/test",
+       // userAuthenticator);
+       // systemBackup.setRemoteBases(remoteBases);
+       //
+       // systemBackup.run();
+       //
+       // fsm.close();
+       // } catch (FileSystemException e) {
+       // // TODO Auto-generated catch block
+       // e.printStackTrace();
+       // System.exit(1);
+       // }
+       //
+       // // wait
+       // try {
+       // Thread.sleep(120 * 1000);
+       // } catch (InterruptedException e) {
+       // e.printStackTrace();
+       // }
+       // }
+       // }
+}
diff --git a/pom.xml b/pom.xml
index 361161015110be2dcc5422ec978ba96042a10f0c..4da560d1579de7e0d9a1b2bc0f7f6b0de15355c3 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,7 @@
                <module>org.argeo.eclipse.ui.rap</module>
                <!-- CMS -->
                <module>org.argeo.node.api</module>
+               <module>org.argeo.maintenance</module>
                <module>org.argeo.cms</module>
                <module>org.argeo.cms.ui</module>
                <!-- CMS Workbench -->