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.33
Committed: Wed Mar 14 01:34:25 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
Changes since 1.32: +30 -26 lines
Log Message:
New dependency checking. The old method was to attempt to start a Component, and
if it failed, it probably had a depdency problem. The approach now is to ask the
Component to perform a dependency check first, then if this suceeds, have a go
at actually starting it up.
The actual dependency check is a bit neater and more precise than before, and
should be much more fool proof. The order the components are specified in the
default.properties file is now irrelevant, although the "correct" order would
certainly increase booting time.

File Contents

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