ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/WebFeeder.java
Revision: 1.11
Committed: Thu Mar 15 14:30:55 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.10: +155 -65 lines
Log Message:
Added support for deleting old alert files.

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.7 package uk.org.iscream.client;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.7 import uk.org.iscream.componentmanager.*;
6     import uk.org.iscream.core.*;
7     import uk.org.iscream.util.*;
8 tdb 1.2 import java.io.*;
9 tdb 1.1
10     /**
11     * Provides a feed to the webpage system.
12     *
13 tdb 1.11 * !! There may also be need to have a Thread to grab any
14     * !! required config (groups, "nice names, etc) and dump
15     * !! that to a file.
16 tdb 1.9 *
17 tdb 1.2 * @author $Author: tdb1 $
18 tdb 1.11 * @version $Id: WebFeeder.java,v 1.10 2001/03/15 04:42:13 tdb1 Exp $
19 tdb 1.1 */
20 tdb 1.11 public class WebFeeder extends Thread {
21 tdb 1.1
22     //---FINAL ATTRIBUTES---
23    
24     /**
25     * The current CVS revision of this class
26     */
27 tdb 1.11 public static final String REVISION = "$Revision: 1.10 $";
28    
29     /**
30     * Default check period in seconds (30 minutes)
31     */
32     public final int DEFAULT_CHECK_PERIOD = 1800;
33    
34     /**
35     * Delete alerts older than this in seconds, default.
36     */
37     public final int DEFAULT_AGE = 3600;
38 tdb 1.1
39     //---STATIC METHODS---
40    
41     /**
42     * Return a reference to the single class.
43     * Construct it if it does not already exist, otherwise just return the reference.
44     */
45     public static WebFeeder getInstance() {
46     if (_instance == null){
47     _instance = new WebFeeder();
48     }
49     return _instance;
50     }
51    
52     //---CONSTRUCTORS---
53 tdb 1.11
54     /**
55     * Construct a new WebFeeder. This will also wipe out any
56     * old Alerts, as these can't be carried from one session
57     * until the next.
58     */
59 tdb 1.1 private WebFeeder() {
60     // do something, or nothing.. but must be private
61 tdb 1.8 // don't need to cleanup latest data
62 tdb 1.9
63     // -- cleanup old alerts
64     // get config proxy
65     ConfigurationProxy cp = ConfigurationProxy.getInstance();
66     // get file locations
67     String rootPath, alertSubDir, alertFileName;
68     try {
69     // work out where things are
70     rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
71     alertSubDir = cp.getProperty("WebFeeder", "WebFeeder.alertSubDir");
72 tdb 1.10 File alertsDir = new File(rootPath+"/"+alertSubDir);
73     if(deleteContents(alertsDir)) {
74     _logger.write(this.toString(), Logger.DEBUG, "Deleted all files and directories from: "+rootPath+"/"+alertSubDir);
75     } else {
76     _logger.write(this.toString(), Logger.WARNING, "Failed to delete all files and directories from: "+rootPath+"/"+alertSubDir);
77 tdb 1.9 }
78     // cleanup complete
79     } catch (PropertyNotFoundException e) {
80     _logger.write(this.toString(), Logger.ERROR, "Failed to cleanup on construction, due to failing to get config for Alert Data: "+e);
81     // just leave it at that
82     }
83 tdb 1.11
84     // set our name and startup
85     setName("client.WebFeeder");
86     start();
87 tdb 1.1 }
88    
89     //---PUBLIC METHODS---
90    
91 tdb 1.11 /**
92     * Thread loop, will check at intervals for any files
93     * that need to be "cleaned up". This will normally
94     * be OK and FINAL alerts that have been around for longer
95     * than a specified period of time.
96     */
97     public void run() {
98     boolean running = true;
99     // get config proxy
100     ConfigurationProxy cp = ConfigurationProxy.getInstance();
101     // loop round
102     while(running) {
103     // get our check period
104     int checkPeriod = 0;
105     try {
106     checkPeriod = Integer.parseInt(cp.getProperty("WebFeeder", "WebFeeder.checkPeriod"));
107     } catch (NumberFormatException e) {
108     checkPeriod = DEFAULT_CHECK_PERIOD;
109     _logger.write(toString(), Logger.WARNING, "Erronous WebFeeder.checkPeriod value in configuration using default of " + checkPeriod + " seconds");
110     } catch (PropertyNotFoundException e) {
111     checkPeriod = DEFAULT_CHECK_PERIOD;
112     _logger.write(toString(), Logger.WARNING, "WebFeeder.checkPeriod value unavailable using default of " + checkPeriod + " seconds");
113     }
114     // wait for the check period
115     try {
116     Thread.sleep(checkPeriod * 1000);
117     } catch (InterruptedException e) {
118     }
119    
120     // get alerts directory
121     String rootPath, alertSubDir, alertFileName;
122     try {
123     rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
124     alertSubDir = cp.getProperty("WebFeeder", "WebFeeder.alertSubDir");
125     alertFileName = cp.getProperty("WebFeeder", "WebFeeder.alertFileName");
126     } catch (PropertyNotFoundException e) {
127     _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Alert Data: "+e);
128     // bail out
129     continue;
130     }
131    
132     // get the "age" barrier
133     int deleteOlderThan = 0;
134     try {
135     deleteOlderThan = Integer.parseInt(cp.getProperty("WebFeeder", "WebFeeder.alertDeleteOlderThan"));
136     } catch (NumberFormatException e) {
137     deleteOlderThan = DEFAULT_AGE;
138     _logger.write(toString(), Logger.WARNING, "Erronous WebFeeder.alertDeleteOlderThan value in configuration using default of " + deleteOlderThan + " seconds");
139     } catch (PropertyNotFoundException e) {
140     deleteOlderThan = DEFAULT_AGE;
141     _logger.write(toString(), Logger.WARNING, "WebFeeder.alertDeleteOlderThan value unavailable using default of " + deleteOlderThan + " seconds");
142     }
143    
144     // list the files
145     String alertsPath = rootPath+"/"+alertSubDir;
146     File alertsDir = new File(alertsPath);
147     File[] contents = alertsDir.listFiles();
148     for(int i=0; i < contents.length; i++) {
149     File hostdir = contents[i];
150     File[] hostdirContents = hostdir.listFiles();
151     for(int j=0; j < hostdirContents.length; j++) {
152     File alertFile = hostdirContents[j];
153     String filename = alertFile.getName();
154     if(filename.endsWith(Alert.alertLevels[0]) ||
155     filename.endsWith(Alert.alertLevels[Alert.alertLevels.length-1])) {
156     // it ends with either OK or FINAL
157     // ... so we can check it for deletion
158     long lastModified = alertFile.lastModified();
159     long age = System.currentTimeMillis() - lastModified;
160     if(age > ((long) deleteOlderThan*1000)) {
161     // it's also older than our age to delete older than
162     if(!alertFile.delete()) {
163     _logger.write(this.toString(), Logger.WARNING, "Failed to delete the following 'old' alert file: "+alertFile.getPath());
164     }
165     }
166     }
167     }
168     }
169     // check through, deleting those passed the age barrier
170     }
171     }
172 tdb 1.1
173 tdb 1.11 /**
174     * Handles an XMLPacket. This will write it out to disk
175     * in an appropriate manner.
176     *
177     * @param packet the XMLPacket to write
178     */
179 tdb 1.1 public void receiveXMLPacket(XMLPacket packet) {
180 tdb 1.4 String packetType = packet.getParam("packet.attributes.type");
181     if(packetType == null || !packetType.equals("data")) {
182     // bail out, without warning
183     // this is probably a heartbeat or similar
184     return;
185     }
186 tdb 1.2 // get config proxy
187     ConfigurationProxy cp = ConfigurationProxy.getInstance();
188     // get file locations
189     String rootPath, latestSubDir, latestFileName;
190     try {
191     rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
192     latestSubDir = cp.getProperty("WebFeeder", "WebFeeder.latestSubDir");
193     latestFileName = cp.getProperty("WebFeeder", "WebFeeder.latestFileName");
194     } catch (PropertyNotFoundException e) {
195     _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Latest Data: "+e);
196     // bail out
197     return;
198     }
199     // get raw data
200     String data = packet.printAll();
201 tdb 1.3 String hostname = packet.getParam("packet.attributes.machine_name");
202 tdb 1.2 // set paths
203     String destDir = rootPath+"/"+latestSubDir+"/"+hostname;
204 tdb 1.11 File outDir = new File(destDir);
205 tdb 1.2 String destFile = destDir+"/"+latestFileName;
206 tdb 1.3 File outFile = new File(destFile);
207 tdb 1.11 // write the data out
208     writeData(outDir, outFile, data);
209 tdb 1.1 }
210    
211 tdb 1.11 /**
212     * Handles an Alert. This will write it out to disk
213     * in an appropriate manner.
214     *
215     * @param alert the Alert object to write
216     */
217 tdb 1.1 public void receiveAlert(Alert alert) {
218 tdb 1.5 // get config proxy
219     ConfigurationProxy cp = ConfigurationProxy.getInstance();
220     // get file locations
221     String rootPath, alertSubDir, alertFileName;
222     try {
223     rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
224     alertSubDir = cp.getProperty("WebFeeder", "WebFeeder.alertSubDir");
225     alertFileName = cp.getProperty("WebFeeder", "WebFeeder.alertFileName");
226     } catch (PropertyNotFoundException e) {
227     _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Alert Data: "+e);
228     // bail out
229     return;
230     }
231     // get raw data
232     String data = alert.printAll();
233     String hostname = alert.getSource();
234     // set paths
235     String destDir = rootPath+"/"+alertSubDir+"/"+hostname;
236 tdb 1.9 File outDir = new File(destDir);
237 tdb 1.8 String destFile = destDir+"/"+alertFileName+"."+String.valueOf(alert.getInitialAlertTime());
238 tdb 1.9 File outFile;
239     // check if we're at a special "end case" (OK or FINAL)
240     if(alert.getLevel()==0 || alert.getLevel()==Alert.alertLevels.length-1) {
241     File oldFile = new File(destFile);
242 tdb 1.10 outFile = new File(destFile+"."+Alert.alertLevels[alert.getLevel()]);
243 tdb 1.9 if(!oldFile.renameTo(outFile)) {
244     _logger.write(this.toString(), Logger.WARNING, "Failed to rename old file, "+oldFile.getPath()+" to new file, "+outFile.getPath());
245     }
246     } else {
247     outFile = new File(destFile);
248     }
249 tdb 1.11 // write the data out
250     writeData(outDir, outFile, data);
251     }
252    
253     /**
254     * Overrides the {@link java.lang.Object#toString() Object.toString()}
255     * method to provide clean logging (every class should have this).
256     *
257     * This uses the uk.org.iscream.util.FormatName class
258     * to format the toString()
259     *
260     * @return the name of this class and its CVS revision
261     */
262     public String toString() {
263     return FormatName.getName(
264     _name,
265     getClass().getName(),
266     REVISION);
267     }
268    
269     //---PRIVATE METHODS---
270    
271     /**
272     * Attempts to write "data" to "outFile" in "outDir".
273     *
274     * Performs checks to create the directories, and the file.
275     * Does not "return" anything to indicate failure or success.
276     *
277     * @param outDir the directory to put the file in
278     * @param outFile the filename to put the data in
279     * @param data the String of data to write
280     */
281     private void writeData(File outDir, File outFile, String data) {
282 tdb 1.5 // try to create directory
283     if(!outDir.exists()) {
284     if(!outDir.mkdirs()) {
285     // didn't exist, and we couldn't make it
286     _logger.write(this.toString(), Logger.ERROR, "Failed to create directory: "+outDir.getPath());
287     // bail out
288     return;
289     }
290     }
291     // directory has been made, check file exists
292     if(!outFile.exists()) {
293     try {
294     outFile.createNewFile();
295     } catch (IOException e) {
296     _logger.write(this.toString(), Logger.ERROR, "Failed to create file: "+e);
297     // bail out
298     return;
299     }
300     }
301     // file should now exist
302     if(outFile.canWrite()) {
303     PrintWriter out;
304     try {
305 tdb 1.8 out = new PrintWriter(new FileWriter(outFile));
306 tdb 1.5 out.println(data);
307     out.close();
308     } catch (IOException e) {
309     _logger.write(this.toString(), Logger.ERROR, "Failed to write file: "+e);
310     }
311     }
312     else {
313     _logger.write(this.toString(), Logger.ERROR, "File not writeable: "+outFile.getPath());
314     }
315 tdb 1.1 }
316 tdb 1.10
317     /**
318     * Iterates through dir (a directory) and deletes
319     * all files and subdirectories.
320     *
321     * @param dir the directory to clear
322     * @return true if it succeeded
323     */
324     private boolean deleteContents(File dir) {
325     boolean success = true;
326     if(dir.isDirectory()) {
327     // is a directory
328     File[] contents = dir.listFiles();
329     for(int i=0; i < contents.length; i++) {
330     File sub = contents[i];
331     if(sub.isDirectory()) {
332     // lets get recursive
333     success = success & deleteContents(sub);
334     }
335     // it's a file or empty dir
336     success = success & sub.delete();
337     }
338     }
339     else {
340     // not a directory?
341     success=false;
342     }
343     return success;
344     }
345    
346 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
347    
348     //---ATTRIBUTES---
349    
350     /**
351     * This is the friendly identifier of the
352     * component this class is running in.
353     * eg, a Filter may be called "filter1",
354     * If this class does not have an owning
355     * component, a name from the configuration
356     * can be placed here. This name could also
357     * be changed to null for utility classes.
358     */
359     private String _name = ClientMain.NAME;
360    
361     /**
362     * This holds a reference to the
363     * system logger that is being used.
364     */
365     private Logger _logger = ReferenceManager.getInstance().getLogger();
366    
367     //---STATIC ATTRIBUTES---
368    
369     /**
370     * A reference to the single instance of this class
371     */
372     private static WebFeeder _instance;
373    
374     }