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
(Generate patch)

Comparing projects/cms/source/server/uk/org/iscream/cms/server/client/WebFeeder.java (file contents):
Revision 1.2 by tdb, Thu Mar 8 20:57:35 2001 UTC vs.
Revision 1.11 by tdb, Thu Mar 15 14:30:55 2001 UTC

# Line 1 | Line 1
1   //---PACKAGE DECLARATION---
2 < package uk.ac.ukc.iscream.client;
2 > package uk.org.iscream.client;
3  
4   //---IMPORTS---
5 < import uk.ac.ukc.iscream.componentmanager.*;
6 < import uk.ac.ukc.iscream.core.*;
7 < import uk.ac.ukc.iscream.util.*;
5 > import uk.org.iscream.componentmanager.*;
6 > import uk.org.iscream.core.*;
7 > import uk.org.iscream.util.*;
8   import java.io.*;
9  
10   /**
11   * Provides a feed to the webpage system.
12   *
13 + * !! 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 + *
17   * @author  $Author$
18   * @version $Id$
19   */
20 < public class WebFeeder {
20 > public class WebFeeder extends Thread {
21  
22   //---FINAL ATTRIBUTES---
23  
# Line 22 | Line 26 | public class WebFeeder {
26       */
27      public static final String REVISION = "$Revision$";
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 +    
39   //---STATIC METHODS---
40  
41      /**
# Line 36 | Line 50 | public class WebFeeder {
50      }
51  
52   //---CONSTRUCTORS---
53 <
53 >    
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      private WebFeeder() {
60          // do something, or nothing.. but must be private
61 +        // don't need to cleanup latest data
62 +        
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 +            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 +            }
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 +        
84 +        // set our name and startup
85 +        setName("client.WebFeeder");
86 +        start();
87      }
88  
89   //---PUBLIC METHODS---
90      
91 <    // TO BE COMPLETED
92 <    // The following two methods should process and save
93 <    // XMLPackets and Alerts, in a directory structure that
94 <    // has been defined by the web page designer.
91 >    /**
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      
173 <    // There may also be need to have a Thread to grab any
174 <    // required config (groups, "nice names, etc) and dump
175 <    // that to a file.
176 <    
173 >    /**
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      public void receiveXMLPacket(XMLPacket packet) {
180 +        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          // get config proxy
187          ConfigurationProxy cp = ConfigurationProxy.getInstance();
188          // get file locations
# Line 68 | Line 198 | public class WebFeeder {
198          }
199          // get raw data
200          String data = packet.printAll();
201 <        String hostname = packet.getParam("packet.attributes.host_name");
201 >        String hostname = packet.getParam("packet.attributes.machine_name");
202          // set paths
203          String destDir = rootPath+"/"+latestSubDir+"/"+hostname;
204 +        File outDir = new File(destDir);
205          String destFile = destDir+"/"+latestFileName;
206 <        // write data
206 >        File outFile = new File(destFile);
207 >        // write the data out
208 >        writeData(outDir, outFile, data);
209 >    }
210 >    
211 >    /**
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 >    public void receiveAlert(Alert alert) {
218 >        // 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          File outDir = new File(destDir);
237 <        if(outDir.mkdirs()) {
238 <            File outFile = new File(destFile);
239 <            if(outFile.canWrite()) {
240 <                PrintWriter out;
241 <                try {
242 <                    out = new PrintWriter(new FileWriter(outFile));
243 <                    out.println(data);
244 <                    out.close();
85 <                } catch (IOException e) {
86 <                    _logger.write(this.toString(), Logger.ERROR, "Failed to write file: "+e);
87 <                }
237 >        String destFile = destDir+"/"+alertFileName+"."+String.valueOf(alert.getInitialAlertTime());
238 >        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 >            outFile = new File(destFile+"."+Alert.alertLevels[alert.getLevel()]);
243 >            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 <                _logger.write(this.toString(), Logger.ERROR, "File not readable: "+outFile.getPath());
91 <            }
246 >        } else {
247 >            outFile = new File(destFile);
248          }
249 <        else {
250 <            _logger.write(this.toString(), Logger.ERROR, "Failed to create directory: "+outDir.getPath());
95 <        }
249 >        // write the data out
250 >        writeData(outDir, outFile, data);
251      }
252      
98    public void receiveAlert(Alert alert) {
99        // process and save
100    }
101    
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.ac.ukc.iscream.util.FormatName class
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
# Line 116 | Line 267 | public class WebFeeder {
267      }
268  
269   //---PRIVATE METHODS---
270 <
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 >        // 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 >                out = new PrintWriter(new FileWriter(outFile));
306 >                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 >    }
316 >    
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   //---ACCESSOR/MUTATOR METHODS---
347  
348   //---ATTRIBUTES---

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines