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.15
Committed: Fri Mar 16 16:47:33 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.14: +9 -3 lines
Log Message:
Trying to explain what I'm doing better.

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