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.14 by tdb, Fri Mar 16 16:43:50 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 +    /**
40 +     * The default path seperator, here for convienience
41 +     */
42 +    private final String sep = File.separator;
43 +    
44   //---STATIC METHODS---
45  
46      /**
# Line 36 | Line 55 | public class WebFeeder {
55      }
56  
57   //---CONSTRUCTORS---
58 <
58 >    
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      private WebFeeder() {
65          // do something, or nothing.. but must be private
66 +        // don't need to cleanup latest data
67 +        
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 +            File alertsDir = new File(rootPath, alertSubDir);
78 +            if(deleteContents(alertsDir)) {
79 +                _logger.write(this.toString(), Logger.DEBUG, "Deleted all files and directories from: "+rootPath+sep+alertSubDir);
80 +            } else {
81 +                _logger.write(this.toString(), Logger.WARNING, "Failed to delete all files and directories from: "+rootPath+sep+alertSubDir);
82 +            }
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 +        
89 +        // set our name and startup
90 +        setName("client.WebFeeder");
91 +        start();
92      }
93  
94   //---PUBLIC METHODS---
95      
96 <    // TO BE COMPLETED
97 <    // The following two methods should process and save
98 <    // XMLPackets and Alerts, in a directory structure that
99 <    // has been defined by the web page designer.
96 >    /**
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 >            // list the files and delete as appropriate
150 >            File alertsDir = new File(rootPath, alertSubDir);
151 >            File[] contents = alertsDir.listFiles();
152 >            for(int i=0; i < contents.length; i++) {
153 >                File hostdir = contents[i];
154 >                if(hostdir.isDirectory()) {
155 >                    File[] hostdirContents = hostdir.listFiles();
156 >                    for(int j=0; j < hostdirContents.length; j++) {
157 >                        File alertFile = hostdirContents[j];
158 >                        String filename = alertFile.getName();
159 >                        if(filename.endsWith(Alert.alertLevels[0]) ||
160 >                           filename.endsWith(Alert.alertLevels[Alert.alertLevels.length-1])) {
161 >                            // it ends with either OK or FINAL
162 >                            // ... so we can check it for deletion
163 >                            long lastModified = alertFile.lastModified();
164 >                            long age = System.currentTimeMillis() - lastModified;
165 >                            if(age > ((long) deleteOlderThan*1000)) {
166 >                                // it's also older than our age to delete older than
167 >                                if(!alertFile.delete()) {
168 >                                    _logger.write(this.toString(), Logger.WARNING, "Failed to delete the following 'old' alert file: "+alertFile.getPath());
169 >                                }
170 >                            }
171 >                        }
172 >                    }
173 >                }
174 >            }
175 >        }
176 >    }
177      
178 <    // There may also be need to have a Thread to grab any
179 <    // required config (groups, "nice names, etc) and dump
180 <    // that to a file.
181 <    
178 >    /**
179 >     * Handles an XMLPacket. This will write it out to disk
180 >     * in an appropriate manner.
181 >     *
182 >     * @param packet the XMLPacket to write
183 >     */
184      public void receiveXMLPacket(XMLPacket packet) {
185 +        String packetType = packet.getParam("packet.attributes.type");
186 +        if(packetType == null || !packetType.equals("data")) {
187 +            // bail out, without warning
188 +            // this is probably a heartbeat or similar
189 +            return;
190 +        }
191          // get config proxy
192          ConfigurationProxy cp = ConfigurationProxy.getInstance();
193          // get file locations
# Line 68 | Line 203 | public class WebFeeder {
203          }
204          // get raw data
205          String data = packet.printAll();
206 <        String hostname = packet.getParam("packet.attributes.host_name");
206 >        String hostname = packet.getParam("packet.attributes.machine_name");
207          // set paths
208 <        String destDir = rootPath+"/"+latestSubDir+"/"+hostname;
209 <        String destFile = destDir+"/"+latestFileName;
210 <        // write data
211 <        File outDir = new File(destDir);
77 <        if(outDir.mkdirs()) {
78 <            File outFile = new File(destFile);
79 <            if(outFile.canWrite()) {
80 <                PrintWriter out;
81 <                try {
82 <                    out = new PrintWriter(new FileWriter(outFile));
83 <                    out.println(data);
84 <                    out.close();
85 <                } catch (IOException e) {
86 <                    _logger.write(this.toString(), Logger.ERROR, "Failed to write file: "+e);
87 <                }
88 <            }
89 <            else {
90 <                _logger.write(this.toString(), Logger.ERROR, "File not readable: "+outFile.getPath());
91 <            }
92 <        }
93 <        else {
94 <            _logger.write(this.toString(), Logger.ERROR, "Failed to create directory: "+outDir.getPath());
95 <        }
208 >        File outDir = new File(rootPath, latestSubDir+sep+hostname);
209 >        File outFile = new File(rootPath, latestSubDir+sep+hostname+sep+latestFileName);
210 >        // write the data out
211 >        writeData(outDir, outFile, data);
212      }
213      
214 +    /**
215 +     * Handles an Alert. This will write it out to disk
216 +     * in an appropriate manner.
217 +     *
218 +     * @param alert the Alert object to write
219 +     */
220      public void receiveAlert(Alert alert) {
221 <        // process and save
221 >        // get config proxy
222 >        ConfigurationProxy cp = ConfigurationProxy.getInstance();
223 >        // get file locations
224 >        String rootPath, alertSubDir, alertFileName;
225 >        try {
226 >            rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
227 >            alertSubDir = cp.getProperty("WebFeeder", "WebFeeder.alertSubDir");
228 >            alertFileName = cp.getProperty("WebFeeder", "WebFeeder.alertFileName");
229 >        } catch (PropertyNotFoundException e) {
230 >            _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Alert Data: "+e);
231 >            // bail out
232 >            return;
233 >        }
234 >        // get raw data
235 >        String data = alert.printAll();
236 >        String hostname = alert.getSource();
237 >        // set paths
238 >        File outDir = new File(rootPath, alertSubDir+sep+hostname);
239 >        String destFile = alertSubDir+sep+hostname+sep+alertFileName+"."+String.valueOf(alert.getInitialAlertTime());
240 >        File outFile;
241 >        // check if we're at a special "end case" (OK or FINAL)
242 >        if(alert.getLevel()==0 || alert.getLevel()==Alert.alertLevels.length-1) {
243 >            File oldFile = new File(rootPath, destFile);
244 >            outFile = new File(rootPath, destFile+"."+Alert.alertLevels[alert.getLevel()]);
245 >            if(!oldFile.renameTo(outFile)) {
246 >                _logger.write(this.toString(), Logger.WARNING, "Failed to rename old file, "+oldFile.getPath()+" to new file, "+outFile.getPath());
247 >            }
248 >        } else {
249 >            outFile = new File(rootPath, destFile);
250 >        }
251 >        // write the data out
252 >        writeData(outDir, outFile, data);
253      }
254      
255      /**
256       * Overrides the {@link java.lang.Object#toString() Object.toString()}
257       * method to provide clean logging (every class should have this).
258       *
259 <     * This uses the uk.ac.ukc.iscream.util.FormatName class
259 >     * This uses the uk.org.iscream.util.FormatName class
260       * to format the toString()
261       *
262       * @return the name of this class and its CVS revision
# Line 116 | Line 269 | public class WebFeeder {
269      }
270  
271   //---PRIVATE METHODS---
272 <
272 >    
273 >    /**
274 >     * Attempts to write "data" to "outFile" in "outDir".
275 >     *
276 >     * Performs checks to create the directories, and the file.
277 >     * Does not "return" anything to indicate failure or success.
278 >     *
279 >     * @param outDir the directory to put the file in
280 >     * @param outFile the filename to put the data in
281 >     * @param data the String of data to write
282 >     */
283 >    private void writeData(File outDir, File outFile, String data) {
284 >        // try to create directory
285 >        if(!outDir.exists()) {
286 >            if(!outDir.mkdirs()) {
287 >                // didn't exist, and we couldn't make it
288 >                _logger.write(this.toString(), Logger.ERROR, "Failed to create directory: "+outDir.getPath());
289 >                // bail out
290 >                return;
291 >            }
292 >        }
293 >        // directory has been made, check file exists
294 >        if(!outFile.exists()) {
295 >            try {
296 >                outFile.createNewFile();
297 >            } catch (IOException e) {
298 >                _logger.write(this.toString(), Logger.ERROR, "Failed to create file: "+e);
299 >                // bail out
300 >                return;
301 >            }
302 >        }
303 >        // file should now exist
304 >        if(outFile.canWrite()) {
305 >            PrintWriter out;
306 >            try {
307 >                out = new PrintWriter(new FileWriter(outFile));
308 >                out.println(data);
309 >                out.close();
310 >            } catch (IOException e) {
311 >                _logger.write(this.toString(), Logger.ERROR, "Failed to write file: "+e);
312 >            }
313 >        }
314 >        else {
315 >            _logger.write(this.toString(), Logger.ERROR, "File not writeable: "+outFile.getPath());
316 >        }
317 >    }
318 >    
319 >    /**
320 >     * Iterates through dir (a directory) and deletes
321 >     * all files and subdirectories.
322 >     *
323 >     * @param dir the directory to clear
324 >     * @return true if it succeeded
325 >     */
326 >    private boolean deleteContents(File dir) {
327 >        boolean success = true;
328 >        if(dir.isDirectory()) {
329 >            // is a directory
330 >            File[] contents = dir.listFiles();
331 >            for(int i=0; i < contents.length; i++) {
332 >                File sub = contents[i];
333 >                if(sub.isDirectory()) {
334 >                    // lets get recursive
335 >                    success = success & deleteContents(sub);
336 >                }
337 >                // it's a file or empty dir
338 >                success = success & sub.delete();
339 >            }
340 >        }
341 >        else {
342 >            // not a directory?
343 >            success=false;
344 >        }
345 >        return success;
346 >    }
347 >        
348   //---ACCESSOR/MUTATOR METHODS---
349  
350   //---ATTRIBUTES---

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines