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.13
Committed: Fri Mar 16 02:40:04 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.12: +3 -3 lines
Log Message:
Missed this in the last change.

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.13 * @version $Id: WebFeeder.java,v 1.12 2001/03/15 22:20:41 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.13 public static final String REVISION = "$Revision: 1.12 $";
28 tdb 1.11
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.12 File alertsDir = new File(rootPath, alertSubDir);
73 tdb 1.10 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 tdb 1.12 // list the files and delete as appropriate
145     File alertsDir = new File(rootPath, alertSubDir);
146 tdb 1.11 File[] contents = alertsDir.listFiles();
147     for(int i=0; i < contents.length; i++) {
148     File hostdir = contents[i];
149 tdb 1.12 if(hostdir.isDirectory()) {
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 tdb 1.11 }
166     }
167     }
168     }
169     }
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 tdb 1.12 File outDir = new File(rootPath, latestSubDir+"/"+hostname);
204     File outFile = new File(rootPath, latestSubDir+"/"+hostname+"/"+latestFileName);
205 tdb 1.11 // write the data out
206     writeData(outDir, outFile, data);
207 tdb 1.1 }
208    
209 tdb 1.11 /**
210     * Handles an Alert. This will write it out to disk
211     * in an appropriate manner.
212     *
213     * @param alert the Alert object to write
214     */
215 tdb 1.1 public void receiveAlert(Alert alert) {
216 tdb 1.5 // get config proxy
217     ConfigurationProxy cp = ConfigurationProxy.getInstance();
218     // get file locations
219     String rootPath, alertSubDir, alertFileName;
220     try {
221     rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
222     alertSubDir = cp.getProperty("WebFeeder", "WebFeeder.alertSubDir");
223     alertFileName = cp.getProperty("WebFeeder", "WebFeeder.alertFileName");
224     } catch (PropertyNotFoundException e) {
225     _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Alert Data: "+e);
226     // bail out
227     return;
228     }
229     // get raw data
230     String data = alert.printAll();
231     String hostname = alert.getSource();
232     // set paths
233 tdb 1.12 File outDir = new File(rootPath, alertSubDir+"/"+hostname);
234     String destFile = alertSubDir+"/"+hostname+"/"+alertFileName+"."+String.valueOf(alert.getInitialAlertTime());
235 tdb 1.9 File outFile;
236     // check if we're at a special "end case" (OK or FINAL)
237     if(alert.getLevel()==0 || alert.getLevel()==Alert.alertLevels.length-1) {
238 tdb 1.12 File oldFile = new File(rootPath, destFile);
239     outFile = new File(rootPath, destFile+"."+Alert.alertLevels[alert.getLevel()]);
240 tdb 1.9 if(!oldFile.renameTo(outFile)) {
241     _logger.write(this.toString(), Logger.WARNING, "Failed to rename old file, "+oldFile.getPath()+" to new file, "+outFile.getPath());
242     }
243     } else {
244 tdb 1.13 outFile = new File(rootPath, destFile);
245 tdb 1.9 }
246 tdb 1.11 // write the data out
247     writeData(outDir, outFile, data);
248     }
249    
250     /**
251     * Overrides the {@link java.lang.Object#toString() Object.toString()}
252     * method to provide clean logging (every class should have this).
253     *
254     * This uses the uk.org.iscream.util.FormatName class
255     * to format the toString()
256     *
257     * @return the name of this class and its CVS revision
258     */
259     public String toString() {
260     return FormatName.getName(
261     _name,
262     getClass().getName(),
263     REVISION);
264     }
265    
266     //---PRIVATE METHODS---
267    
268     /**
269     * Attempts to write "data" to "outFile" in "outDir".
270     *
271     * Performs checks to create the directories, and the file.
272     * Does not "return" anything to indicate failure or success.
273     *
274     * @param outDir the directory to put the file in
275     * @param outFile the filename to put the data in
276     * @param data the String of data to write
277     */
278     private void writeData(File outDir, File outFile, String data) {
279 tdb 1.5 // try to create directory
280     if(!outDir.exists()) {
281     if(!outDir.mkdirs()) {
282     // didn't exist, and we couldn't make it
283     _logger.write(this.toString(), Logger.ERROR, "Failed to create directory: "+outDir.getPath());
284     // bail out
285     return;
286     }
287     }
288     // directory has been made, check file exists
289     if(!outFile.exists()) {
290     try {
291     outFile.createNewFile();
292     } catch (IOException e) {
293     _logger.write(this.toString(), Logger.ERROR, "Failed to create file: "+e);
294     // bail out
295     return;
296     }
297     }
298     // file should now exist
299     if(outFile.canWrite()) {
300     PrintWriter out;
301     try {
302 tdb 1.8 out = new PrintWriter(new FileWriter(outFile));
303 tdb 1.5 out.println(data);
304     out.close();
305     } catch (IOException e) {
306     _logger.write(this.toString(), Logger.ERROR, "Failed to write file: "+e);
307     }
308     }
309     else {
310     _logger.write(this.toString(), Logger.ERROR, "File not writeable: "+outFile.getPath());
311     }
312 tdb 1.1 }
313 tdb 1.10
314     /**
315     * Iterates through dir (a directory) and deletes
316     * all files and subdirectories.
317     *
318     * @param dir the directory to clear
319     * @return true if it succeeded
320     */
321     private boolean deleteContents(File dir) {
322     boolean success = true;
323     if(dir.isDirectory()) {
324     // is a directory
325     File[] contents = dir.listFiles();
326     for(int i=0; i < contents.length; i++) {
327     File sub = contents[i];
328     if(sub.isDirectory()) {
329     // lets get recursive
330     success = success & deleteContents(sub);
331     }
332     // it's a file or empty dir
333     success = success & sub.delete();
334     }
335     }
336     else {
337     // not a directory?
338     success=false;
339     }
340     return success;
341     }
342    
343 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
344    
345     //---ATTRIBUTES---
346    
347     /**
348     * This is the friendly identifier of the
349     * component this class is running in.
350     * eg, a Filter may be called "filter1",
351     * If this class does not have an owning
352     * component, a name from the configuration
353     * can be placed here. This name could also
354     * be changed to null for utility classes.
355     */
356     private String _name = ClientMain.NAME;
357    
358     /**
359     * This holds a reference to the
360     * system logger that is being used.
361     */
362     private Logger _logger = ReferenceManager.getInstance().getLogger();
363    
364     //---STATIC ATTRIBUTES---
365    
366     /**
367     * A reference to the single instance of this class
368     */
369     private static WebFeeder _instance;
370    
371     }