1
2
3
4
5
6
7 package gov.bnl.gums.configuration;
8
9 import gov.bnl.gums.GUMS;
10 import gov.bnl.gums.account.AccountMapper;
11 import gov.bnl.gums.groupToAccount.GroupToAccountMapping;
12 import gov.bnl.gums.hostToGroup.HostToGroupMapping;
13 import gov.bnl.gums.persistence.PersistenceFactory;
14 import gov.bnl.gums.userGroup.UserGroup;
15 import gov.bnl.gums.userGroup.VomsServer;
16
17 import java.io.BufferedWriter;
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.FileNotFoundException;
21 import java.io.FileOutputStream;
22 import java.io.FileWriter;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.text.DateFormat;
26 import java.text.SimpleDateFormat;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Date;
31 import java.util.Iterator;
32
33 import org.apache.commons.logging.*;
34
35
36
37
38
39
40
41 public class FileConfigurationStore implements ConfigurationStore {
42
43
44
45
46
47
48 static public void copyFile(String source, String target) {
49 try {
50 if (System.getProperty("os.name").indexOf("Linux")!=-1) {
51
52 String[] cpArgs = new String[4];
53 cpArgs[0] = "/bin/cp";
54 cpArgs[1] = "-f";
55 cpArgs[2] = source;
56 cpArgs[3] = target;
57 if (Runtime.getRuntime().exec(cpArgs).waitFor() != 0)
58 throw new RuntimeException("Error copying file");
59 }
60 else {
61 FileInputStream fis = new FileInputStream(source);
62 FileOutputStream fos = new FileOutputStream(target);
63 byte[] buf = new byte[1024];
64 int i = 0;
65 while((i=fis.read(buf))!=-1)
66 fos.write(buf, 0, i);
67 fis.close();
68 fos.close();
69 }
70 } catch (FileNotFoundException e) {
71 e.printStackTrace();
72 } catch (IOException e) {
73 e.printStackTrace();
74 } catch (InterruptedException e) {
75 e.printStackTrace();
76 }
77 }
78
79
80
81
82
83
84
85 static public void moveFile(String source, String target) {
86 copyFile(source, target);
87 new File(source).delete();
88 }
89
90 private Log log = LogFactory.getLog(FileConfigurationStore.class);
91 private Log gumsSiteAdminLog = LogFactory.getLog(GUMS.siteAdminLog);
92 private Log gumsResourceAdminLog = LogFactory.getLog(GUMS.resourceAdminLog);
93 private Configuration conf;
94 private Date lastRetrival;
95 private String configBackupDir = null;
96 private String configPath = null;
97 private String schemaPath = null;
98 private String transformPath = null;
99 private DateFormat format = new SimpleDateFormat("yyyy_MM_dd_HHmm");
100 private String version;
101
102
103
104
105
106 public FileConfigurationStore() {
107 URL resource = getClass().getClassLoader().getResource("gums.config");
108 if (resource!=null) {
109 String configDir = resource.getPath().replace("/gums.config", "");
110 this.configPath = configDir+"/gums.config";
111 this.schemaPath = configDir+"/gums.config.schema";
112 this.transformPath = configDir+"/gums.config.transform";
113 this.configBackupDir = configDir+"/backup";
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126 public FileConfigurationStore(String configDir, String resourceDir, String version, boolean create) {
127 this.version = version;
128 this.configPath = configDir+"/gums.config";
129 this.schemaPath = resourceDir+"/gums.config.schema";
130 this.transformPath = resourceDir+"/gums.config.transform";
131 this.configBackupDir = configDir+"/backup";
132
133 if (create && !(new File(configPath).exists())) {
134 try {
135 BufferedWriter out = new BufferedWriter(new FileWriter(configPath));
136 out.write("<?xml version='1.0' encoding='UTF-8'?>\n\n"+
137 "<gums version='"+version+"'>\n\n"+
138 "\t<persistenceFactories>\n\n"+
139 "\t\t<hibernatePersistenceFactory\n"+
140 "\t\t\tname='mysql'\n"+
141 "\t\t\tdescription=''\n"+
142 "\t\t\thibernate.connection.driver_class='com.mysql.jdbc.Driver'\n"+
143 "\t\t\thibernate.dialect='net.sf.hibernate.dialect.MySQLDialect'\n"+
144 "\t\t\thibernate.connection.url='jdbc:mysql://localhost.localdomain:3306/GUMS_1_1'\n"+
145 "\t\t\thibernate.connection.username='gums'\n"+
146 "\t\t\thibernate.connection.password=''\n"+
147 "\t\t\thibernate.connection.autoReconnect='true'\n"+
148 "\t\t\thibernate.c3p0.min_size='3'\n"+
149 "\t\t\thibernate.c3p0.max_size='20'\n"+
150 "\t\t\thibernate.c3p0.timeout='180' />\n\n"+
151 "\t</persistenceFactories>\n\n"+
152 "\t<userGroups>\n\n"+
153 "\t\t<manualUserGroup\n"+
154 "\t\t\tname='admins'\n"+
155 "\t\t\tdescription=''\n"+
156 "\t\t\tpersistenceFactory='mysql'\n"+
157 "\t\t\taccess='write'/>\n\n"+
158 "\t</userGroups>\n\n"+
159 "</gums>");
160 out.close();
161 } catch (IOException e1) {
162 gumsResourceAdminLog.error("Could not create gums.config: " + e1.getMessage());
163 }
164 }
165 }
166
167 public void deleteBackupConfiguration(String dateStr) {
168 new File(configBackupDir+"/gums.config."+dateStr).delete();
169 }
170
171 public Collection getBackupConfigDates() {
172 ArrayList backupConfigDates = new ArrayList();
173 File dir = new File(configBackupDir);
174 String[] children = dir.list();
175 if (children!=null) {
176 for (int i=0; i<children.length; i++) {
177 backupConfigDates.add( children[i].substring(children[i].lastIndexOf(".")+1) );
178 }
179 }
180 Collections.sort(backupConfigDates);
181 return backupConfigDates;
182 }
183
184 public boolean isActive() {
185 log.debug("Checking whether gums.config is present");
186 return new File(configPath).exists();
187 }
188
189 public boolean isReadOnly() {
190 return false;
191 }
192
193 public synchronized Configuration retrieveConfiguration() {
194 try {
195 if ((lastRetrival == null) || (lastRetrival.before(lastModification())))
196 reloadConfiguration();
197 } catch (Exception e) {
198 throw new RuntimeException(e.getMessage());
199 }
200 return conf;
201 }
202
203 public synchronized Configuration restoreConfiguration(String dateStr) {
204 moveFile(configPath, configBackupDir + "/gums.config~");
205 copyFile(configBackupDir + "/gums.config." + dateStr, configPath);
206 moveFile(configBackupDir + "/gums.config~", configBackupDir + "/gums.config.prev");
207 return retrieveConfiguration();
208 }
209
210 public synchronized void setConfiguration(Configuration conf, boolean backupCopy) throws Exception {
211 log.trace("Configuration set programically");
212 gumsResourceAdminLog.info("Configuration set programically");
213 gumsSiteAdminLog.info("Configuration set programically");
214 if (conf == null)
215 throw new RuntimeException("Configuration has not been loaded");
216
217 log.debug("Attempting to store configuration");
218 String tempGumsConfigPath = configPath+"~";
219
220 BufferedWriter out;
221 out = new BufferedWriter(new FileWriter(tempGumsConfigPath));
222
223 out.write("<?xml version='1.0' encoding='UTF-8'?>\n\n");
224
225 out.write("<gums version='"+version+"'>\n\n");
226
227
228 if( conf.getPersistenceFactories().size()>0 ) {
229 out.write("\t<persistenceFactories>\n\n");
230 Iterator it = conf.getPersistenceFactories().values().iterator();
231 while( it.hasNext() ) {
232 PersistenceFactory persistenceFactory = (PersistenceFactory)it.next();
233 out.write( persistenceFactory.toXML() );
234 }
235 out.write("\t</persistenceFactories>\n\n");
236 }
237
238
239 if( conf.getVomsServers().size()>0 ) {
240 out.write("\t<vomsServers>\n\n");
241 Iterator it = conf.getVomsServers().values().iterator();
242 while( it.hasNext() ) {
243 VomsServer vo = (VomsServer)it.next();
244 out.write( vo.toXML() );
245 }
246 out.write("\t</vomsServers>\n\n");
247 }
248
249
250 if( conf.getUserGroups().size()>0 ) {
251 out.write("\t<userGroups>\n\n");
252 Iterator it = conf.getUserGroups().values().iterator();
253 while( it.hasNext() ) {
254 UserGroup userGroup = (UserGroup)it.next();
255 out.write( userGroup.toXML() );
256 }
257 out.write("\t</userGroups>\n\n");
258 }
259
260
261 if( conf.getAccountMappers().size()>0 ) {
262 out.write("\t<accountMappers>\n\n");
263 Iterator it = conf.getAccountMappers().values().iterator();
264 while( it.hasNext() ) {
265 AccountMapper accountMapper = (AccountMapper)it.next();
266 out.write( accountMapper.toXML() );
267 }
268 out.write("\t</accountMappers>\n\n");
269 }
270
271
272 if( conf.getAccountMappers().size()>0 ) {
273 out.write("\t<groupToAccountMappings>\n\n");
274 Iterator it = conf.getGroupToAccountMappings().values().iterator();
275 while( it.hasNext() ) {
276 GroupToAccountMapping groupToAccountMapping = (GroupToAccountMapping)it.next();
277 out.write( groupToAccountMapping.toXML() );
278 }
279 out.write("\t</groupToAccountMappings>\n\n");
280 }
281
282
283 if( conf.getAccountMappers().size()>0 ) {
284 out.write("\t<hostToGroupMappings>\n\n");
285 Iterator it = conf.getHostToGroupMappings().iterator();
286 while( it.hasNext() ) {
287 HostToGroupMapping hostToGroupMapping = (HostToGroupMapping)it.next();
288 out.write( hostToGroupMapping.toXML() );
289 }
290 out.write("\t</hostToGroupMappings>\n\n");
291 }
292
293 out.write("</gums>");
294
295 out.close();
296
297
298 this.conf = ConfigurationToolkit.loadConfiguration(tempGumsConfigPath, schemaPath);
299
300
301 new File(configBackupDir).mkdir();
302 if (!backupCopy && new File(configPath).exists())
303 copyFile(configPath, configBackupDir+"/gums.config.prev");
304
305
306 moveFile(tempGumsConfigPath, (backupCopy?configBackupDir+"/gums.config."+format.format(new Date()):configPath));
307 }
308
309 private Date lastModification() {
310 try {
311 File file = new File(configPath);
312 return new Date(file.lastModified());
313 } catch (Exception e) {
314 gumsResourceAdminLog.fatal("The configuration wasn't read properly. GUMS is not operational.", e);
315 return null;
316 }
317 }
318
319 private void reloadConfiguration() {
320 conf = null;
321 try {
322 if (ConfigurationToolkit.getVersion(configPath).equals("1.1")) {
323 copyFile(configPath,configPath+".1.1");
324 Configuration configuration = ConfigurationTransform.doTransform(configPath, transformPath);
325 setConfiguration(configuration, false);
326 }
327
328 log.debug("Attempting to load configuration from gums.config");
329 conf = ConfigurationToolkit.loadConfiguration(configPath, schemaPath);
330 log.trace("Configuration reloaded from '" + configPath + "'");
331 gumsResourceAdminLog.info("Configuration reloaded from '" + configPath + "'");
332 gumsSiteAdminLog.info("Configuration reloaded from '" + configPath + "'");
333 lastRetrival = new Date();
334 } catch (Exception e) {
335 gumsResourceAdminLog.error("The configuration wasn't read correctly: " + e.getMessage());
336 log.error("The configuration wasn't read correctly.", e);
337 throw new RuntimeException("The configuration wasn't read correctly: " + e.getMessage());
338 }
339 }
340 }