From: Mathieu Baudier Date: Fri, 5 Oct 2012 09:15:18 +0000 (+0000) Subject: Improve error handling by backups X-Git-Tag: argeo-commons-2.1.30~823 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=a49ea54cef01bfd8b57aa235e3d69ae5ed243147;p=lgpl%2Fargeo-commons.git Improve error handling by backups git-svn-id: https://svn.argeo.org/commons/trunk@5592 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/base/runtime/org.argeo.util/src/main/java/org/argeo/ArgeoException.java b/base/runtime/org.argeo.util/src/main/java/org/argeo/ArgeoException.java index 343b6c947..03ac4958e 100644 --- a/base/runtime/org.argeo.util/src/main/java/org/argeo/ArgeoException.java +++ b/base/runtime/org.argeo.util/src/main/java/org/argeo/ArgeoException.java @@ -29,10 +29,21 @@ public class ArgeoException extends RuntimeException { super(message, e); } - /** @deprecated use {@link #ArgeoException(String, Throwable)} instead. */ - @Deprecated - public ArgeoException(Throwable cause) { - super(cause); + /** + * Chain the messages of all causes (one per line, starts with a line + * return) without all the stack + */ + public static String chainCausesMessages(Throwable t) { + StringBuffer buf = new StringBuffer(); + chainCauseMessage(buf, t); + return buf.toString(); } + /** Recursive chaining of messages */ + private static void chainCauseMessage(StringBuffer buf, Throwable t) { + buf.append('\n').append(' ').append(t.getClass().getCanonicalName()) + .append(": ").append(t.getMessage()); + if (t.getCause() != null) + chainCauseMessage(buf, t.getCause()); + } } diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/ArgeoServerException.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/ArgeoServerException.java deleted file mode 100644 index 368ee5a5b..000000000 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/ArgeoServerException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2007-2012 Mathieu Baudier - * - * 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.server; - -import org.argeo.ArgeoException; - -/** @deprecated use {@link ArgeoException} instead */ -public class ArgeoServerException extends ArgeoException { - private static final long serialVersionUID = 1L; - - public ArgeoServerException(String message) { - super(message); - } - - public ArgeoServerException(Throwable cause) { - super(cause); - } - - public ArgeoServerException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AbstractAtomicBackup.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AbstractAtomicBackup.java index dd47651a6..637e78cf6 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AbstractAtomicBackup.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AbstractAtomicBackup.java @@ -22,6 +22,15 @@ public abstract class AbstractAtomicBackup implements AtomicBackup { this.name = name; } + public void init() { + if (name == null) + throw new ArgeoException("Atomic backup name must be set"); + } + + public void destroy() { + + } + @Override public String backup(FileSystemManager fileSystemManager, String backupsBase, BackupContext backupContext, @@ -64,6 +73,10 @@ public abstract class AbstractAtomicBackup implements AtomicBackup { this.name = name; } + public String getName() { + return name; + } + public void setCompression(String compression) { this.compression = compression; } diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AtomicBackup.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AtomicBackup.java index 2c06cda4a..873068f06 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AtomicBackup.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/AtomicBackup.java @@ -5,6 +5,9 @@ import org.apache.commons.vfs.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 @@ -14,5 +17,6 @@ public interface AtomicBackup { * @return the VFS URI of the generated file or directory */ public String backup(FileSystemManager fileSystemManager, - String backupsBase, BackupContext backupContext, FileSystemOptions opts); + String backupsBase, BackupContext backupContext, + FileSystemOptions opts); } diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/BackupUtils.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/BackupUtils.java index 88480b318..9bac5db95 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/BackupUtils.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/BackupUtils.java @@ -1,7 +1,6 @@ package org.argeo.server.backup; import org.apache.commons.vfs.FileObject; -import org.apache.commons.vfs.FileSystemException; /** Backup utilities */ public class BackupUtils { @@ -10,12 +9,12 @@ public class BackupUtils { if (fo != null) { try { fo.close(); - } catch (FileSystemException e) { + } catch (Exception e) { // silent } } } - + /** Prevents instantiation */ private BackupUtils() { } diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/MySqlBackup.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/MySqlBackup.java index 8d729eaff..e4ec54e34 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/MySqlBackup.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/MySqlBackup.java @@ -15,12 +15,19 @@ public class MySqlBackup extends OsCallBackup { } public MySqlBackup(String dbUser, String dbPassword, String dbName) { - super(dbName); + super(dbName + ".sql"); this.dbUser = dbUser; this.dbPassword = dbPassword; this.dbName = dbName; } + @Override + public void init() { + if (getName() == null) + setName(dbName + ".sql"); + super.init(); + } + @Override public void writeBackup(FileObject targetFo) { if (getCommand() == null) diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/OsCallBackup.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/OsCallBackup.java index eeca1ccc7..989c29a68 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/OsCallBackup.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/OsCallBackup.java @@ -58,9 +58,8 @@ public class OsCallBackup extends AbstractAtomicBackup { } catch (ExecuteException e) { byte[] err = errBos.toByteArray(); String errStr = new String(err); - throw new ArgeoException("Process " + commandLine - + " failed with exit value " + e.getExitValue() + ": " - + errStr, e); + throw new ArgeoException("Process " + commandLine + " failed (" + + e.getExitValue() + "): " + errStr, e); } catch (Exception e) { byte[] err = errBos.toByteArray(); String errStr = new String(err); diff --git a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/SystemBackup.java b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/SystemBackup.java index 54bb29384..a8149ee54 100644 --- a/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/SystemBackup.java +++ b/server/runtime/org.argeo.server.core/src/main/java/org/argeo/server/backup/SystemBackup.java @@ -59,7 +59,7 @@ public class SystemBackup implements Runnable { backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts); } catch (Exception e) { - failures.add(e.getMessage()); + failures.add("Purge " + backupsBase + " failed: " + e.getMessage()); log.error("Purge of " + backupsBase + " failed", e); } @@ -71,8 +71,14 @@ public class SystemBackup implements Runnable { if (log.isDebugEnabled()) log.debug("Performed backup " + target); } catch (Exception e) { - failures.add(e.getMessage()); - log.error("Atomic backup failed", e); + String msg = "Atomic backup " + atomickBackup.getName() + + " failed: " + ArgeoException.chainCausesMessages(e); + failures.add(msg); + log.error(msg); + if (log.isTraceEnabled()) + log.trace( + "Stacktrace of atomic backup " + + atomickBackup.getName() + " failure.", e); } } @@ -82,14 +88,20 @@ public class SystemBackup implements Runnable { FileObject remoteBaseFo = null; UserAuthenticator auth = remoteBases.get(remoteBase); + // authentication + FileSystemOptions remoteOpts = new FileSystemOptions(); try { - // authentication - FileSystemOptions remoteOpts = new FileSystemOptions(); 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 + '/' @@ -99,7 +111,9 @@ public class SystemBackup implements Runnable { log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo); // } - } catch (FileSystemException e) { + } catch (Exception e) { + failures.add("Dispatch to " + remoteBase + " failed: " + + e.getMessage()); log.error( "Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " @@ -109,11 +123,16 @@ public class SystemBackup implements Runnable { BackupUtils.closeFOQuietly(remoteBaseFo); } + int failureCount = 0; if (failures.size() > 0) { StringBuffer buf = new StringBuffer(); - for (String failure : failures) - buf.append('\n').append(failure); - throw new ArgeoException("Errors when running the backup," + for (String failure : failures) { + buf.append('\n').append(failureCount).append(" - ") + .append(failure); + failureCount++; + } + throw new ArgeoException(failureCount + + " error(s) when running the backup," + " check the logs and the backups as soon as possible." + buf); }