1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.argeo.maintenance.backup.vfs;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.commons.vfs2.FileObject;
26 import org.apache.commons.vfs2.FileSystemException;
27 import org.apache.commons.vfs2.FileSystemManager;
28 import org.apache.commons.vfs2.FileSystemOptions;
29 import org.apache.commons.vfs2.Selectors;
30 import org.apache.commons.vfs2.UserAuthenticator;
31 import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
32 import org.argeo.maintenance.MaintenanceException;
33 import org.argeo.util.LangUtils;
34
35
36
37
38
39 public class SystemBackup implements Runnable {
40 private final static Log log = LogFactory.getLog(SystemBackup.class);
41
42 private FileSystemManager fileSystemManager;
43 private UserAuthenticator userAuthenticator = null;
44
45 private String backupsBase;
46 private String systemName;
47
48 private List<AtomicBackup> atomicBackups = new ArrayList<AtomicBackup>();
49 private BackupPurge backupPurge = new SimpleBackupPurge();
50
51 private Map<String, UserAuthenticator> remoteBases = new HashMap<String, UserAuthenticator>();
52
53 @Override
54 public void run() {
55 if (atomicBackups.size() == 0)
56 throw new MaintenanceException("No atomic backup listed");
57 List<String> failures = new ArrayList<String>();
58
59 SimpleBackupContext backupContext = new SimpleBackupContext(fileSystemManager, backupsBase, systemName);
60
61
62 FileSystemOptions opts = new FileSystemOptions();
63 try {
64 DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(opts, userAuthenticator);
65 } catch (FileSystemException e) {
66 throw new MaintenanceException("Cannot create authentication", e);
67 }
68
69 try {
70
71 backupPurge.purge(fileSystemManager, backupsBase, systemName, backupContext.getDateFormat(), opts);
72 } catch (Exception e) {
73 failures.add("Purge " + backupsBase + " failed: " + e.getMessage());
74 log.error("Purge of " + backupsBase + " failed", e);
75 }
76
77
78 for (AtomicBackup atomickBackup : atomicBackups) {
79 try {
80 String target = atomickBackup.backup(fileSystemManager, backupsBase, backupContext, opts);
81 if (log.isDebugEnabled())
82 log.debug("Performed backup " + target);
83 } catch (Exception e) {
84 String msg = "Atomic backup " + atomickBackup.getName() + " failed: "
85 + LangUtils.chainCausesMessages(e);
86 failures.add(msg);
87 log.error(msg);
88 if (log.isTraceEnabled())
89 log.trace("Stacktrace of atomic backup " + atomickBackup.getName() + " failure.", e);
90 }
91 }
92
93
94 for (String remoteBase : remoteBases.keySet()) {
95 FileObject localBaseFo = null;
96 FileObject remoteBaseFo = null;
97 UserAuthenticator auth = remoteBases.get(remoteBase);
98
99
100 FileSystemOptions remoteOpts = new FileSystemOptions();
101 try {
102 DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(remoteOpts, auth);
103 backupPurge.purge(fileSystemManager, remoteBase, systemName, backupContext.getDateFormat(), remoteOpts);
104 } catch (Exception e) {
105 failures.add("Purge " + remoteBase + " failed: " + e.getMessage());
106 log.error("Cannot purge " + remoteBase, e);
107 }
108
109 try {
110 localBaseFo = fileSystemManager.resolveFile(backupsBase + '/' + backupContext.getRelativeFolder(),
111 opts);
112 remoteBaseFo = fileSystemManager.resolveFile(remoteBase + '/' + backupContext.getRelativeFolder(),
113 remoteOpts);
114 remoteBaseFo.copyFrom(localBaseFo, Selectors.SELECT_ALL);
115 if (log.isDebugEnabled())
116 log.debug("Copied backup to " + remoteBaseFo + " from " + localBaseFo);
117
118 } catch (Exception e) {
119 failures.add("Dispatch to " + remoteBase + " failed: " + e.getMessage());
120 log.error("Cannot dispatch backups from " + backupContext.getRelativeFolder() + " to " + remoteBase, e);
121 }
122 BackupUtils.closeFOQuietly(localBaseFo);
123 BackupUtils.closeFOQuietly(remoteBaseFo);
124 }
125
126 int failureCount = 0;
127 if (failures.size() > 0) {
128 StringBuffer buf = new StringBuffer();
129 for (String failure : failures) {
130 buf.append('\n').append(failureCount).append(" - ").append(failure);
131 failureCount++;
132 }
133 throw new MaintenanceException(failureCount + " error(s) when running the backup,"
134 + " check the logs and the backups as soon as possible." + buf);
135 }
136 }
137
138 public void setFileSystemManager(FileSystemManager fileSystemManager) {
139 this.fileSystemManager = fileSystemManager;
140 }
141
142 public void setBackupsBase(String backupsBase) {
143 this.backupsBase = backupsBase;
144 }
145
146 public void setSystemName(String name) {
147 this.systemName = name;
148 }
149
150 public void setAtomicBackups(List<AtomicBackup> atomicBackups) {
151 this.atomicBackups = atomicBackups;
152 }
153
154 public void setBackupPurge(BackupPurge backupPurge) {
155 this.backupPurge = backupPurge;
156 }
157
158 public void setUserAuthenticator(UserAuthenticator userAuthenticator) {
159 this.userAuthenticator = userAuthenticator;
160 }
161
162 public void setRemoteBases(Map<String, UserAuthenticator> remoteBases) {
163 this.remoteBases = remoteBases;
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 }