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.14
Committed: Fri Mar 16 16:43:50 2001 UTC (23 years, 3 months ago) by tdb
Branch: MAIN
Changes since 1.13: +13 -8 lines
Log Message:
Sorted the seperator character out :)

File Contents

# Content
1 //---PACKAGE DECLARATION---
2 package uk.org.iscream.client;
3
4 //---IMPORTS---
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: tdb1 $
18 * @version $Id: WebFeeder.java,v 1.13 2001/03/16 02:40:04 tdb1 Exp $
19 */
20 public class WebFeeder extends Thread {
21
22 //---FINAL ATTRIBUTES---
23
24 /**
25 * The current CVS revision of this class
26 */
27 public static final String REVISION = "$Revision: 1.13 $";
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 /**
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
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 /**
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 /**
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
194 String rootPath, latestSubDir, latestFileName;
195 try {
196 rootPath = cp.getProperty("WebFeeder", "WebFeeder.rootPath");
197 latestSubDir = cp.getProperty("WebFeeder", "WebFeeder.latestSubDir");
198 latestFileName = cp.getProperty("WebFeeder", "WebFeeder.latestFileName");
199 } catch (PropertyNotFoundException e) {
200 _logger.write(this.toString(), Logger.ERROR, "Failed to get config for Latest Data: "+e);
201 // bail out
202 return;
203 }
204 // get raw data
205 String data = packet.printAll();
206 String hostname = packet.getParam("packet.attributes.machine_name");
207 // set paths
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 // 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.org.iscream.util.FormatName class
260 * to format the toString()
261 *
262 * @return the name of this class and its CVS revision
263 */
264 public String toString() {
265 return FormatName.getName(
266 _name,
267 getClass().getName(),
268 REVISION);
269 }
270
271 //---PRIVATE METHODS---
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---
351
352 /**
353 * This is the friendly identifier of the
354 * component this class is running in.
355 * eg, a Filter may be called "filter1",
356 * If this class does not have an owning
357 * component, a name from the configuration
358 * can be placed here. This name could also
359 * be changed to null for utility classes.
360 */
361 private String _name = ClientMain.NAME;
362
363 /**
364 * This holds a reference to the
365 * system logger that is being used.
366 */
367 private Logger _logger = ReferenceManager.getInstance().getLogger();
368
369 //---STATIC ATTRIBUTES---
370
371 /**
372 * A reference to the single instance of this class
373 */
374 private static WebFeeder _instance;
375
376 }