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/MonitorManager.java
Revision: 1.20
Committed: Fri Jul 25 14:35:29 2003 UTC (20 years, 9 months ago) by tdb
Branch: MAIN
Changes since 1.19: +10 -3 lines
Log Message:
Fix bug #6. On occasions a NullPointer would creep out of this bit of code.
My guess is it was either a Null packet, or a packet with no data type,
both of which shouldn't really happen. Put in kludges to catch them, but
it would be nice to know why it happened ;)

File Contents

# User Rev Content
1 tdb 1.15 /*
2     * i-scream central monitoring system
3 tdb 1.16 * http://www.i-scream.org.uk
4 tdb 1.15 * Copyright (C) 2000-2002 i-scream
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20    
21 tdb 1.1 //---PACKAGE DECLARATION---
22 tdb 1.14 package uk.org.iscream.cms.server.client;
23 tdb 1.1
24     //---IMPORTS---
25 tdb 1.14 import uk.org.iscream.cms.server.componentmanager.*;
26     import uk.org.iscream.cms.server.core.*;
27 tdb 1.18 import uk.org.iscream.cms.util.*;
28 tdb 1.1 import java.util.*;
29    
30     /**
31     * A manager for the Monitors.
32     *
33 ajm 1.13 * This class starts by loading all the monitors as specificed in the configuration.
34     * These monitors should implement the PluginMonitor interface.
35     *
36     * This class then takes the feed of data coming in over CORBA from
37     * the ClientServant queue. This data is then looked at to determine
38 tdb 1.19 * type. It then places it into either a data queue, or an other
39     * queue, and all data in the the all queue.
40 ajm 1.13 *
41     * Monitors then read the data off the queue that they are interested in
42     * and process the data accordingly.
43     *
44 tdb 1.15 * @author $Author: tdb $
45 tdb 1.20 * @version $Id: MonitorManager.java,v 1.19 2003/02/24 20:18:46 tdb Exp $
46 tdb 1.1 */
47 ajm 1.11 public class MonitorManager extends Thread {
48 tdb 1.1
49     //---FINAL ATTRIBUTES---
50    
51     /**
52     * The current CVS revision of this class
53     */
54 tdb 1.20 public static final String REVISION = "$Revision: 1.19 $";
55 tdb 1.1
56     //---STATIC METHODS---
57    
58 ajm 1.3 /**
59     * Return a reference to the single class.
60     * Construct it if it does not already exist, otherwise just return the reference.
61     */
62 tdb 1.12 public synchronized static MonitorManager getInstance() {
63 ajm 1.3 if (_instance == null){
64     _instance = new MonitorManager();
65     }
66     return _instance;
67     }
68    
69 tdb 1.1 //---CONSTRUCTORS---
70    
71 ajm 1.13 /**
72     * Constructs a new MonitorManager.
73     * This initialises all the queues and loads
74     * all the Monitors that have been specified in the configuration
75     */
76 ajm 1.3 private MonitorManager() {
77 tdb 1.5 // set our name
78     setName("client.MonitorManager");
79    
80 ajm 1.3 _queue = ClientMain._monitorQueue;
81     _qID = _queue.getQueue();
82     _logger.write(toString(), Logger.SYSINIT, "Initialising");
83     _logger.write(toString(), Logger.SYSMSG, "Creating monitor pipeline for plugin monitors ...");
84    
85 tdb 1.8 // get the config proxy
86     ConfigurationProxy cp = ConfigurationProxy.getInstance();
87    
88 tdb 1.9 // get the configuration for our outgoing queue's
89    
90     // see if these Queue's need a size limit
91     try {
92     int queueSizeLimit = Integer.parseInt(cp.getProperty(_name, "Queue.SizeLimit"));
93     String queueRemoveAlgorithm = cp.getProperty(_name, "Queue.RemoveAlgorithm");
94     int algorithm = StringUtils.getStringPos(queueRemoveAlgorithm, Queue.algorithms);
95     if(algorithm != -1) {
96 tdb 1.19 _logger.write(toString(), Logger.DEBUG, "Starting 3 Queues with size limit of "+queueSizeLimit+", using remove algorithm "+queueRemoveAlgorithm);
97 tdb 1.9 // we have valid values, so lets start it.
98     _dataQueue = new Queue(queueSizeLimit, algorithm);
99     _otherQueue = new Queue(queueSizeLimit, algorithm);
100 tdb 1.10 _allQueue = new Queue(queueSizeLimit, algorithm);
101 tdb 1.9 }
102     else {
103     _logger.write(toString(), Logger.WARNING, "Bad Queue Algorithm configuration, not known: "+queueRemoveAlgorithm);
104     // just don't activate a limit
105     _dataQueue = new Queue();
106     _otherQueue = new Queue();
107 tdb 1.10 _allQueue = new Queue();
108 tdb 1.9 }
109     } catch (PropertyNotFoundException e) {
110     _logger.write(toString(), Logger.DEBUG, "Optional config not set: "+e);
111     // just don't activate a limit
112     _dataQueue = new Queue();
113     _otherQueue = new Queue();
114 tdb 1.10 _allQueue = new Queue();
115 tdb 1.9 } catch (NumberFormatException e) {
116     _logger.write(toString(), Logger.WARNING, "Bad Queue SizeLimit configuration: "+e);
117     // just don't activate a limit
118     _dataQueue = new Queue();
119     _otherQueue = new Queue();
120 tdb 1.10 _allQueue = new Queue();
121 tdb 1.9 }
122    
123     // startup monitors on these queues
124     try {
125     // try to get the interval, if this fails, we won't start up the monitor
126     int queueMonitorInterval = Integer.parseInt(cp.getProperty(_name, "Queue.MonitorInterval"));
127     _dataQueue.startMonitor(queueMonitorInterval*1000, ClientMain._monitorQueue, _name + " DataQueue");
128     _otherQueue.startMonitor(queueMonitorInterval*1000, ClientMain._monitorQueue, _name + " OtherQueue");
129 tdb 1.10 _allQueue.startMonitor(queueMonitorInterval*1000, ClientMain._monitorQueue, _name + " AllQueue");
130 tdb 1.9 } catch (PropertyNotFoundException e) {
131     _logger.write(toString(), Logger.WARNING, "failed to find queue monitor config, disabling. " + e);
132     }
133    
134 ajm 1.3 // get the configuration for this plug-in setup
135 tdb 1.8 String pluginsPackage, pluginsList;
136     try {
137     pluginsPackage = cp.getProperty(_name, "Monitor.PluginsPackage");
138     pluginsList = cp.getProperty(_name, "Monitor.Plugins");
139     } catch(PropertyNotFoundException e) {
140     _logger.write(toString(), Logger.WARNING, "Unable to get required configuration, Monitor's will not be activated: "+e);
141     // setting these will ensure we don't build a pipeline
142     pluginsPackage = "";
143     pluginsList = "";
144     }
145 ajm 1.3
146     StringTokenizer st = new StringTokenizer(pluginsList, ";");
147    
148     while(st.hasMoreTokens()) {
149     String className = pluginsPackage + "." + st.nextToken() + _suffix;
150     _logger.write(toString(), Logger.DEBUG, "Attempting to create plugin: "+className);
151    
152     // Create an instance of the specified PluginMonitor to include
153     // within the monitorPipe. Add it to the monitorPipeline
154     try {
155     PluginMonitor pm = (PluginMonitor)ClassLoader.getSystemClassLoader().loadClass(className).newInstance();
156     _monitorPipeline.add(pm);
157     _logger.write(toString(), Logger.DEBUG, "Added monitor: "+className+" ("+pm.getDescription()+")");
158     }
159     catch (InstantiationException e){
160     _logger.write(toString(), Logger.ERROR, "Failed to instantiate "+className+" to the plugin monitor pipeline.");
161     _logger.write(toString(), Logger.ERROR, e.getMessage());
162     }
163     catch (Exception e){
164     _logger.write(toString(), Logger.ERROR, "Failed to add "+className+" to the plugin monitor pipeline.");
165     _logger.write(toString(), Logger.ERROR, e.toString());
166     }
167     }
168     _logger.write(toString(), Logger.SYSMSG, "The monitor pipeline has been set up with "+_monitorPipeline.size()+" plugin monitors.");
169 tdb 1.1 }
170    
171     //---PUBLIC METHODS---
172    
173 ajm 1.13 /**
174     * Runs the MonitorManager. This reads data from the
175     * inbound queue (from the ClientServant). And passes
176     * it into the appropriate queue for processing by the monitor
177     * threads.
178     */
179 tdb 1.1 public void run() {
180     boolean run=true;
181 tdb 1.7
182     // keep these out here, saves recreating the object
183     String xml = null;
184 tdb 1.1 while(run) {
185     try {
186 ajm 1.3 xml = (String) _queue.get(_qID);
187 tdb 1.1 }
188     catch(InvalidQueueException e) {
189     _logger.write(toString(), Logger.ERROR, "Queue failure: "+e);
190     }
191    
192     // make an XML packet
193 tdb 1.2 XMLPacket packet = null;
194 tdb 1.1
195 tdb 1.2 try {
196 tdb 1.17 packet = _xmlCache.getXMLPacket(xml);
197 tdb 1.2 } catch(InvalidXMLException e) {
198     _logger.write(toString(), Logger.ERROR, "Invalid XML: "+e);
199     // skip the rest of this loop iteration
200     continue;
201     }
202 tdb 1.20
203     if(packet == null) {
204     _logger.write(toString(), Logger.WARNING, "Got a null packet when parsing: "+xml);
205     // skip to next packet
206     continue;
207     }
208 tdb 1.9
209     // examine the packet and place it in the relevant outgoing queue
210 tdb 1.20 if(packet.getParam("packet.attributes.type") != null &&
211     packet.getParam("packet.attributes.type").equals("data")) {
212 tdb 1.9 _dataQueue.add(packet);
213     }
214     else {
215     _otherQueue.add(packet);
216 tdb 1.1 }
217 tdb 1.10 // always add to all queue
218     _allQueue.add(packet);
219 tdb 1.1 }
220     }
221    
222     /**
223     * Overrides the {@link java.lang.Object#toString() Object.toString()}
224     * method to provide clean logging (every class should have this).
225     *
226 tdb 1.18 * This uses the uk.org.iscream.cms.util.FormatName class
227 tdb 1.1 * to format the toString()
228     *
229     * @return the name of this class and its CVS revision
230     */
231     public String toString() {
232     return FormatName.getName(
233     _name,
234     getClass().getName(),
235     REVISION);
236     }
237    
238     //---PRIVATE METHODS---
239    
240     //---ACCESSOR/MUTATOR METHODS---
241 tdb 1.9
242 ajm 1.13 /**
243     * Allows Monitors to obtain
244     * the queue of data packets
245     */
246 tdb 1.9 public Queue getDataQueue() {
247     return _dataQueue;
248     }
249    
250 ajm 1.13 /**
251     * Allows Monitors to obtain
252     * the queue of all other packets
253     */
254 tdb 1.9 public Queue getOtherQueue() {
255     return _otherQueue;
256     }
257    
258 ajm 1.13 /**
259     * In case a Monitor wants more
260     * than one type of packet,
261     * this queue can be obtained.
262     */
263 tdb 1.10 public Queue getAllQueue() {
264     return _allQueue;
265     }
266    
267 tdb 1.1 //---ATTRIBUTES---
268    
269     /**
270     * This is the friendly identifier of the
271     * component this class is running in.
272     * eg, a Filter may be called "filter1",
273     * If this class does not have an owning
274     * component, a name from the configuration
275     * can be placed here. This name could also
276     * be changed to null for utility classes.
277     */
278     private String _name = ClientMain.NAME;
279    
280     /**
281     * This holds a reference to the
282     * system logger that is being used.
283     */
284     private Logger _logger = ReferenceManager.getInstance().getLogger();
285    
286     /**
287 ajm 1.3 * A reference to the reference manager in use
288     */
289     private ReferenceManager _refman = ReferenceManager.getInstance();
290    
291     /**
292 tdb 1.9 * A reference to our incoming Queue
293 tdb 1.1 */
294     private Queue _queue;
295 ajm 1.3
296     /**
297 tdb 1.9 * Our incoming queue ID
298 ajm 1.3 */
299     private int _qID;
300    
301     /**
302     * file name suffix for plugin monitor classes:
303     */
304     private final String _suffix = "__Monitor";
305    
306     /**
307     * LinkedList for holding the PluginMonitor objects (the pipeline).
308     */
309     private LinkedList _monitorPipeline = new LinkedList();
310 tdb 1.9
311     /**
312     * Outgoing data Queue
313     */
314     private Queue _dataQueue;
315    
316     /**
317     * Outgoing other Queue
318     */
319     private Queue _otherQueue;
320 tdb 1.10
321     /**
322     * Outgoing ALL Queue
323     */
324     private Queue _allQueue;
325 tdb 1.17
326     /**
327     * A reference to the XMLCache in use
328     */
329     private XMLCache _xmlCache = XMLCache.getInstance();
330 tdb 1.9
331 tdb 1.1 //---STATIC ATTRIBUTES---
332 ajm 1.3
333     /**
334     * A reference to the single instance of this class
335     */
336     private static MonitorManager _instance;
337 tdb 1.1
338     }