ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/componentmanager/ComponentManager.java
Revision: 1.43
Committed: Mon May 5 22:05:09 2003 UTC (21 years, 1 month ago) by tdb
Branch: MAIN
Changes since 1.42: +37 -29 lines
Log Message:
Tidy up of the client interface code - more commonly known as the
"right hand side of the server". Right since the start the filter
side of the server has been nice and tree like - every Filter sent
data to another Filter. At the top of the tree there was a "special"
Filter known as the RootFilter, which to the other Filters just
looked like a normal Filter. This was nice, and simple, and expandable.

The Client Interface on the other hand was messy. The root filter
had some hacky wrapper threads which pulled from a queue and pushed
to the relevant client interfaces (one for real time stuff, and the
other for databases). There was no simple room for expandability -
it was all hardwired to do just what was needed at the time.

This commit changes that. A Client Interface now connects to another
Client Interface, with a special one being found in the RootFilter
(yes, maybe that needs a name change now :-). So we can chain client
interfaces, and move other bits and bobs around in the server - for
example, alerting no longer needs to be connected to the Client
Interface, it can connect straight to the RootFilter (or, wherever
the config tells it ;).

Hopefully this sanitizes the underlying layout of the server a bit.

As a final note, I dropped the DBInterface. This used to insert
data in to a MySQL database. We've long since stopped using that,
and it's fallen behind and is way out of date. For now, it's gone
in to the attic.

File Contents

# User Rev Content
1 tdb 1.40 /*
2     * i-scream central monitoring system
3 tdb 1.41 * http://www.i-scream.org.uk
4 tdb 1.40 * 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 ajm 1.1 //---PACKAGE DECLARATION---
22 tdb 1.38 package uk.org.iscream.cms.server.componentmanager;
23 ajm 1.1
24     //---IMPORTS---
25     import java.util.*;
26     import java.io.*;
27 tdb 1.42 import uk.org.iscream.cms.util.*;
28 ajm 1.1
29     /**
30 ajm 1.2 * The component manager is the starting point for all
31     * server side components of the iscream system.
32     * It loads its initial system configuration from the
33     * default properties file, it then starts all the iscream
34     * components as specified in the default.properties under
35 tdb 1.38 * uk.org.iscream.cms.server.ComponentList
36 ajm 1.1 *
37 tdb 1.39 * @author $Author: tdb $
38 tdb 1.43 * @version $Id: ComponentManager.java,v 1.42 2003/02/05 16:43:46 tdb Exp $
39 ajm 1.1 */
40     public class ComponentManager {
41    
42     //---FINAL ATTRIBUTES---
43    
44     /**
45     * The current CVS revision of this class
46     */
47 tdb 1.43 public static final String REVISION = "$Revision: 1.42 $";
48 ajm 1.1
49     /**
50     * The toString() of this class
51     * As it won't be instatiated, this is needed.
52 ajm 1.2 * Not also that we pass a null as the class name (as we are static)
53 ajm 1.1 */
54 ajm 1.2 public static final String toString = FormatName.getName("ComponentManager", null, REVISION);
55 ajm 1.1
56     /**
57     * The default location of the properties file for the system
58     */
59 ajm 1.2 public static final String DEFAULTPROPERTIES = "./etc/default.properties";
60 ajm 1.1
61 ajm 1.22 /**
62 tdb 1.43 * The default time to wait before retrying
63 ajm 1.22 * component.
64     */
65     public static final int DEFAULT_COMPONENT_START_TIMEOUT = 5;
66    
67 ajm 1.1 //---STATIC METHODS---
68    
69     /**
70 ajm 1.2 * The main method which starts the components as
71     * listed in the default.properties file.
72 ajm 1.1 *
73     * @param args the command line arguments
74     */
75     public static void main(String[] args) {
76 ajm 1.36 System.out.println("-----------------------------------------");
77 tdb 1.11 System.out.println("--- i-scream Server Component Manager ---");
78 tdb 1.37 System.out.println("--- (c) 2001 The i-scream Project ---");
79 ajm 1.36 System.out.println("--- (http://www.i-scream.org.uk) ---");
80     System.out.println("-----------------------------------------");
81 tdb 1.43 System.out.println("--- Starting System ---");
82 ajm 1.2
83 ajm 1.1 // get the command line args
84     String defaultProperties = DEFAULTPROPERTIES;
85     String filterName = null;
86 tdb 1.39 String filterManagerName = null;
87 tdb 1.43 String clientInterfaceName = null;
88 tdb 1.11 for(int i=0; i < args.length; i++) {
89 tdb 1.12 if(args[i].equals("-h")) {
90 ajm 1.1 usage();
91 tdb 1.11 }
92 tdb 1.12 else if(args[i].equals("-f")) {
93 tdb 1.39 if(++i < args.length) {
94     filterName = args[i];
95     }
96     else {
97     usage();
98     }
99     }
100     else if(args[i].equals("-fm")) {
101     if(++i < args.length) {
102     filterManagerName = args[i];
103     }
104     else {
105     usage();
106     }
107 tdb 1.11 }
108 tdb 1.43 else if(args[i].equals("-ci")) {
109     if(++i < args.length) {
110     clientInterfaceName = args[i];
111     }
112     else {
113     usage();
114     }
115     }
116 tdb 1.12 else if(args[i].equals("-l")) {
117 tdb 1.39 if(++i < args.length) {
118     defaultProperties = args[i];
119     }
120     else {
121     usage();
122     }
123 tdb 1.11 }
124     else {
125     usage();
126     }
127 ajm 1.1 }
128    
129     // load the default properties file into the system properties
130     System.out.println(toString + ": initialising - using " + defaultProperties);
131     try {
132     Properties initProperties = new Properties(System.getProperties());
133     initProperties.load(new FileInputStream(new File(defaultProperties)));
134     System.setProperties(initProperties);
135     } catch (Exception e) {
136     System.err.println(toString + ": ERROR " + e.getMessage());
137     usage();
138     }
139    
140     // continue to bring the system up
141     System.out.println(toString + ": coming up");
142    
143     // start the ORB by initialising the ReferenceManager
144 ajm 1.2 ReferenceManager refman = ReferenceManager.getInstance();
145 ajm 1.1
146 ajm 1.2 // now the ORB is running, we need to activate our RootPOA
147     // so that we can start serving requests once servants start up
148 ajm 1.1 refman.activatePOA();
149    
150 ajm 1.2 // get the list of components
151 tdb 1.38 String componentList = System.getProperty("uk.org.iscream.cms.server.ComponentList");
152 ajm 1.1 StringTokenizer st = new StringTokenizer(componentList, ";");
153 tdb 1.33 _componentsToStart = new LinkedList();
154 ajm 1.13
155 ajm 1.1 // this could be done using reflection
156     // but..well..we don't ;-p
157     while (st.hasMoreTokens()){
158     String componentName = st.nextToken();
159     Component component = null;
160 ajm 1.13
161 ajm 1.2
162     // ### This is where the list of supported components is checked! ###
163     if (componentName.equalsIgnoreCase("core")) {
164 tdb 1.38 component = new uk.org.iscream.cms.server.core.Core();
165 tdb 1.39 // note the passing of the FilterManagers's name in its constructor
166 ajm 1.3 } else if (componentName.equalsIgnoreCase("filtermanager")) {
167 tdb 1.39 component = new uk.org.iscream.cms.server.filtermanager.FilterManager(filterManagerName);
168 ajm 1.4 } else if (componentName.equalsIgnoreCase("rootfilter")) {
169 tdb 1.38 component = new uk.org.iscream.cms.server.rootfilter.RootFilter();
170 ajm 1.6 } else if (componentName.equalsIgnoreCase("clientinterface")) {
171 tdb 1.43 component = new uk.org.iscream.cms.server.clientinterface.ClientInterfaceMain(clientInterfaceName);
172 ajm 1.7 // note the passing of the Filter's name in its constructor
173     } else if (componentName.equalsIgnoreCase("filter")) {
174 tdb 1.38 component = new uk.org.iscream.cms.server.filter.FilterMain(filterName);
175 tdb 1.30 } else if (componentName.equalsIgnoreCase("client")) {
176 tdb 1.38 component = new uk.org.iscream.cms.server.client.ClientMain();
177 ajm 1.1 }
178 ajm 1.2 // ### Add new component constructors in the above section! ###
179 ajm 1.3
180 ajm 1.22 // build the list of components to start
181 ajm 1.1 if (component != null) {
182 tdb 1.43 _componentsToStart.add(component);
183 ajm 1.13 } else {
184 tdb 1.33 System.err.println(toString + ": WARNING unsupported component not started: "+componentName);
185 ajm 1.13 }
186     }
187    
188 ajm 1.32
189 ajm 1.22
190     // get the value for timeout
191 ajm 1.32
192 ajm 1.28 String confTimeout = null;
193 ajm 1.22 try {
194 tdb 1.38 confTimeout = System.getProperty("uk.org.iscream.cms.server.ComponentTimeout");
195 ajm 1.29 confTimeout.trim();
196 ajm 1.32 _startTimeout = Integer.parseInt(confTimeout);
197 ajm 1.22 } catch (NumberFormatException e) {
198 ajm 1.32 _startTimeout = DEFAULT_COMPONENT_START_TIMEOUT;
199 tdb 1.38 System.err.println(toString + ": unable to read uk.org.iscream.cms.server.ComponentTimeout value (" + confTimeout + "), using default!");
200 ajm 1.22 }
201 ajm 1.32 System.out.println(toString + ": using component start timeout of " + _startTimeout + " seconds");
202 ajm 1.22
203 ajm 1.31 // startup the system components
204     startUp();
205    
206 tdb 1.43 // block on the ORB...in time, management functionality can be placed here.
207     // if we detect a CORBA communication error, we'll restart all the components.
208     // !! this doesn't appear to work !!
209     while(true) {
210     try {
211 ajm 1.31 refman.getORB().run();
212 ajm 1.32 } catch (org.omg.CORBA.COMM_FAILURE e) {
213 ajm 1.31 System.out.println(toString + ": WARNING CORBA communications failure - " + e.getMessage());
214     System.out.println(toString + ": WARNING CORBA connections have been lost - attempting to restart!");
215     }
216     startUp();
217     }
218     }
219    
220     /**
221     * Starts the components as obtained from the configuration.
222     * This method calls the start() methods on all the components.
223     * If a component fails to start due to a CORBA communication
224     * problem, then it catches this and tries to start it again
225 tdb 1.38 * according to uk.org.iscream.cms.server.ComponentTimeout time.
226 ajm 1.31 *
227     * If the server dies and CORBA connections are lost, this method
228     * is called again.
229     */
230     private static void startUp() {
231 tdb 1.43 // now we try and start the beast up
232 ajm 1.32 boolean tryAgain = true;
233     Component component = null;
234    
235 ajm 1.22 // keep trying until we've started all the components.
236     // maybe add support for a limited number of retries
237 ajm 1.13 while(tryAgain) {
238 ajm 1.32 Iterator i = _componentsToStart.iterator();
239 tdb 1.33 LinkedList failedComponents = new LinkedList();
240 ajm 1.22 // go through all the components
241 ajm 1.13 while(i.hasNext()) {
242 tdb 1.43 // get a refence to the component
243     component = (Component) i.next();
244     System.out.println(toString + ": dependency checking component - " + component.toString());
245    
246     // check it's dependencies
247     boolean depOK = component.depCheck();
248     if(depOK) {
249     System.out.println(toString + ": starting component - " + component.toString());
250     // it should be ok to start the component
251     try {
252     // start the component
253 tdb 1.33 component.start();
254     } catch (ComponentStartException e) {
255     // if we get this then there was a problem
256     // that we can't recover from
257     System.err.println(toString + ": ERROR starting component - " + component.toString());
258     System.err.println(toString + ": component reports - " + e.getMessage());
259     System.exit(1);
260     }
261     }
262     else {
263     // it seems the depedencies failed
264     // so we want to try again after a delay
265     System.err.println(toString + ": WARNING Component reported dependency failure");
266 ajm 1.14 System.err.println(toString + ": This could be because it can't communicate with components it needs.");
267 ajm 1.22
268     // make a list of the failed components
269 ajm 1.20 failedComponents.add(component);
270 ajm 1.1 }
271 ajm 1.13 }
272 ajm 1.22
273     // if we had some failed components that we can retry
274 ajm 1.21 if (failedComponents.size() > 0) {
275 ajm 1.14 System.err.println(toString + ": WARNING One or more components failed to start correctly.");
276 ajm 1.32 System.err.println(toString + ": Will try again in " + _startTimeout + " seconds");
277 ajm 1.22
278     // our list is now the failed list
279 ajm 1.32 _componentsToStart = failedComponents;
280 ajm 1.22
281     // sleep for a given timeout
282 tdb 1.43 try {
283 ajm 1.32 Thread.sleep(_startTimeout * 1000);
284 ajm 1.17 } catch (InterruptedException e) {
285     // we're not bothered
286     }
287 ajm 1.22 // otherwise we started everything
288 ajm 1.18 } else {
289 ajm 1.22 // so we set to exit the loop
290 ajm 1.18 tryAgain = false;
291 ajm 1.1 }
292     }
293 tdb 1.43
294     System.out.println(toString + ": running");
295     }
296 ajm 1.3
297     /**
298 ajm 1.1 * A simple method to print the usage of this class.
299     * It never returns, but instead exits to the system
300     * with a value 1, to indicate the system did not start
301     * properly.
302     */
303     public static void usage() {
304 tdb 1.38 System.out.println("USAGE: java uk.org.iscream.cms.server.componentmanager.ComponentManager <option>");
305 tdb 1.8 System.out.println(" or: java -jar iscream.jar <option>");
306 ajm 1.1 System.out.println("WHERE <option>:");
307     System.out.println(" -l <filename> - the location of initial system properties");
308 ajm 1.2 System.out.println(" the default is ./etc/default.properties");
309 ajm 1.1 System.out.println(" -f <name> - the name of the filter (if there is one configured");
310 tdb 1.39 System.out.println(" -fm <name> - the name of the filter manager (if there is one configured");
311 tdb 1.43 System.out.println(" -ci <name> - the name of the client interface (if there is one configured");
312 ajm 1.1 System.out.println(" -h - this help screen");
313     System.exit(1);
314     }
315    
316     //---CONSTRUCTORS---
317    
318     //---PUBLIC METHODS---
319    
320     //---PRIVATE METHODS---
321    
322     //---ACCESSOR/MUTATOR METHODS---
323    
324     //---ATTRIBUTES---
325    
326     //---STATIC ATTRIBUTES---
327 ajm 1.32
328 tdb 1.33 private static LinkedList _componentsToStart;
329 ajm 1.32 private static int _startTimeout = 0;
330 ajm 1.1
331     }