2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.server
.backup
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
23 import org
.apache
.commons
.logging
.Log
;
24 import org
.apache
.commons
.logging
.LogFactory
;
25 import org
.apache
.commons
.vfs
.FileObject
;
26 import org
.apache
.commons
.vfs
.FileSystemException
;
27 import org
.apache
.commons
.vfs
.FileSystemManager
;
28 import org
.apache
.commons
.vfs
.FileSystemOptions
;
29 import org
.apache
.commons
.vfs
.Selectors
;
30 import org
.apache
.commons
.vfs
.UserAuthenticator
;
31 import org
.apache
.commons
.vfs
.auth
.StaticUserAuthenticator
;
32 import org
.apache
.commons
.vfs
.impl
.DefaultFileSystemConfigBuilder
;
33 import org
.apache
.commons
.vfs
.impl
.StandardFileSystemManager
;
34 import org
.argeo
.ArgeoException
;
37 * Combines multiple backups and transfer them to a remote location. Purges
38 * remote and local data based on certain criteria.
40 public class SystemBackup
implements Runnable
{
41 private final static Log log
= LogFactory
.getLog(SystemBackup
.class);
43 private FileSystemManager fileSystemManager
;
44 private UserAuthenticator userAuthenticator
= null;
46 private String backupsBase
;
47 private String systemName
;
49 private List
<AtomicBackup
> atomicBackups
= new ArrayList
<AtomicBackup
>();
50 private BackupPurge backupPurge
= new SimpleBackupPurge();
52 private Map
<String
, UserAuthenticator
> remoteBases
= new HashMap
<String
, UserAuthenticator
>();
56 if (atomicBackups
.size() == 0)
57 throw new ArgeoException("No atomic backup listed");
58 List
<String
> failures
= new ArrayList
<String
>();
60 SimpleBackupContext backupContext
= new SimpleBackupContext(
61 fileSystemManager
, backupsBase
, systemName
);
63 // purge older backups
64 FileSystemOptions opts
= new FileSystemOptions();
66 DefaultFileSystemConfigBuilder
.getInstance().setUserAuthenticator(
67 opts
, userAuthenticator
);
68 } catch (FileSystemException e
) {
69 throw new ArgeoException("Cannot create authentication", e
);
74 backupPurge
.purge(fileSystemManager
, backupsBase
, systemName
,
75 backupContext
.getDateFormat(), opts
);
76 } catch (Exception e
) {
77 failures
.add("Purge " + backupsBase
+ " failed: " + e
.getMessage());
78 log
.error("Purge of " + backupsBase
+ " failed", e
);
82 for (AtomicBackup atomickBackup
: atomicBackups
) {
84 String target
= atomickBackup
.backup(fileSystemManager
,
85 backupsBase
, backupContext
, opts
);
86 if (log
.isDebugEnabled())
87 log
.debug("Performed backup " + target
);
88 } catch (Exception e
) {
89 String msg
= "Atomic backup " + atomickBackup
.getName()
90 + " failed: " + ArgeoException
.chainCausesMessages(e
);
93 if (log
.isTraceEnabled())
95 "Stacktrace of atomic backup "
96 + atomickBackup
.getName() + " failure.", e
);
100 // dispatch to remote
101 for (String remoteBase
: remoteBases
.keySet()) {
102 FileObject localBaseFo
= null;
103 FileObject remoteBaseFo
= null;
104 UserAuthenticator auth
= remoteBases
.get(remoteBase
);
107 FileSystemOptions remoteOpts
= new FileSystemOptions();
109 DefaultFileSystemConfigBuilder
.getInstance()
110 .setUserAuthenticator(remoteOpts
, auth
);
111 backupPurge
.purge(fileSystemManager
, remoteBase
, systemName
,
112 backupContext
.getDateFormat(), remoteOpts
);
113 } catch (Exception e
) {
114 failures
.add("Purge " + remoteBase
+ " failed: "
116 log
.error("Cannot purge " + remoteBase
, e
);
120 localBaseFo
= fileSystemManager
.resolveFile(backupsBase
+ '/'
121 + backupContext
.getRelativeFolder(), opts
);
122 remoteBaseFo
= fileSystemManager
.resolveFile(remoteBase
+ '/'
123 + backupContext
.getRelativeFolder(), remoteOpts
);
124 remoteBaseFo
.copyFrom(localBaseFo
, Selectors
.SELECT_ALL
);
125 if (log
.isDebugEnabled())
126 log
.debug("Copied backup to " + remoteBaseFo
+ " from "
129 } catch (Exception e
) {
130 failures
.add("Dispatch to " + remoteBase
+ " failed: "
133 "Cannot dispatch backups from "
134 + backupContext
.getRelativeFolder() + " to "
137 BackupUtils
.closeFOQuietly(localBaseFo
);
138 BackupUtils
.closeFOQuietly(remoteBaseFo
);
141 int failureCount
= 0;
142 if (failures
.size() > 0) {
143 StringBuffer buf
= new StringBuffer();
144 for (String failure
: failures
) {
145 buf
.append('\n').append(failureCount
).append(" - ")
149 throw new ArgeoException(failureCount
150 + " error(s) when running the backup,"
151 + " check the logs and the backups as soon as possible."
156 public void setFileSystemManager(FileSystemManager fileSystemManager
) {
157 this.fileSystemManager
= fileSystemManager
;
160 public void setBackupsBase(String backupsBase
) {
161 this.backupsBase
= backupsBase
;
164 public void setSystemName(String name
) {
165 this.systemName
= name
;
168 public void setAtomicBackups(List
<AtomicBackup
> atomicBackups
) {
169 this.atomicBackups
= atomicBackups
;
172 public void setBackupPurge(BackupPurge backupPurge
) {
173 this.backupPurge
= backupPurge
;
176 public void setUserAuthenticator(UserAuthenticator userAuthenticator
) {
177 this.userAuthenticator
= userAuthenticator
;
180 public void setRemoteBases(Map
<String
, UserAuthenticator
> remoteBases
) {
181 this.remoteBases
= remoteBases
;
184 public static void main(String args
[]) {
187 StandardFileSystemManager fsm
= new StandardFileSystemManager();
190 SystemBackup systemBackup
= new SystemBackup();
191 systemBackup
.setSystemName("mySystem");
193 .setBackupsBase("/home/mbaudier/dev/src/commons/server/runtime/org.argeo.server.core/target");
194 systemBackup
.setFileSystemManager(fsm
);
196 List
<AtomicBackup
> atomicBackups
= new ArrayList
<AtomicBackup
>();
198 MySqlBackup mySqlBackup
= new MySqlBackup("root", "", "test");
199 atomicBackups
.add(mySqlBackup
);
200 PostgreSqlBackup postgreSqlBackup
= new PostgreSqlBackup(
201 "argeo", "argeo", "gis_template");
202 atomicBackups
.add(postgreSqlBackup
);
203 SvnBackup svnBackup
= new SvnBackup(
204 "/home/mbaudier/tmp/testsvnrepo");
205 atomicBackups
.add(svnBackup
);
207 systemBackup
.setAtomicBackups(atomicBackups
);
209 Map
<String
, UserAuthenticator
> remoteBases
= new HashMap
<String
, UserAuthenticator
>();
210 StaticUserAuthenticator userAuthenticator
= new StaticUserAuthenticator(
211 null, "demo", "demo");
212 remoteBases
.put("sftp://localhost/home/mbaudier/test",
214 systemBackup
.setRemoteBases(remoteBases
);
219 } catch (FileSystemException e
) {
220 // TODO Auto-generated catch block
227 Thread
.sleep(120 * 1000);
228 } catch (InterruptedException e
) {