source: greenstone3/trunk/src/java/org/greenstone/server/Server2.java@ 19543

Last change on this file since 19543 was 19543, checked in by ak19, 15 years ago

Adds url=URL_pending into the llssite.cfg/glisite.cfg file if the server has not yet been started. This is then used by GLI's LocalLibraryServer to work out whether it should luanch a GSI itself, or whether one was already inependently launched (from outside of GLI). If the latter case, GLI will use the GSI that's already open. If the server is never started by GSI server, then the URL-pending line that's still in the configFile is removed to restore the default state.

File size: 12.7 KB
Line 
1
2package org.greenstone.server;
3
4import java.io.BufferedReader;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.FileOutputStream;
8import java.io.InputStreamReader;
9import java.io.IOException;
10import java.net.ServerSocket;
11import java.net.Socket;
12import java.net.URL;
13//import java.net.URLConnection;
14import java.util.Properties;
15import java.util.ArrayList;
16
17import org.apache.log4j.*;
18
19import org.greenstone.server.BaseServer;
20import org.greenstone.server.BaseProperty;
21
22public class Server2 extends BaseServer
23{
24 private static final int WAITING_TIME = 10; // time to wait and check for whether the server is running
25 private static final String URL_PENDING="URL_pending";
26
27 protected String libraryURL;
28
29 private class QuitListener extends Thread
30 {
31 int quitPort = -1;
32 ServerSocket serverSocket = null;
33
34 public QuitListener(int quitport) throws Exception {
35 ///Server2.this.recordSuccess("In QuitListener constructor");
36 this.quitPort = quitport;
37 serverSocket = new ServerSocket(quitPort);
38 }
39
40 public void run() {
41 Socket connection = null;
42
43 try {
44 // wait for a connection
45 connection = serverSocket.accept();
46
47 // read input
48 try {
49 BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
50 String line = null;
51 if((line = reader.readLine()) != null) {
52 if(line.equals("QUIT")) {
53 // Server2.this.recordSuccess("In QuitListener - line is QUIT");
54 reader.close();
55 reader = null;
56 serverSocket.close();
57 serverSocket = null;
58 }
59 }
60 } catch(Exception e) {
61 Server2.this.recordError("Exception in QuitListener thread.");
62 } finally {
63 Server2.this.stop();
64 System.exit(0);
65 }
66 } catch(IOException ioe) {
67 Server2.this.recordError("Server2.QuitListener: Unable to make the connection with the client socket." + ioe);
68 }
69 }
70 }
71
72
73 public Server2(String gsdl2_home, String lang, String configfile, int quitPort)
74 {
75 super(gsdl2_home, lang, configfile, "etc"+File.separator+"logs-gsi");
76 // configfile can be either glisite.cfg or llssite.cfg
77
78 Property = new Server2Property();
79
80 String frame_title = dictionary.get("ServerControl.Frame_Title");
81 server_control_ = new Server2Control(this,frame_title);
82
83 /* Make command tagets for managing Web server */
84 START_CMD = "web-start";
85 RESTART_CMD = "web-restart";
86 CONFIGURE_CMD = "configure-web " + configfile;
87 STOP_CMD = "web-stop";
88
89 // now we can monitor for the quit command if applicable
90 if(quitPort != -1) {
91 // First check if given port is within the range of allowed ports
92 if(PortFinder.isAssignablePortNumber(quitPort)) {
93 try {
94 new QuitListener(quitPort).start();
95 } catch(Exception e) {
96 Server2.this.recordError("Exception constructing the QuitListener thread.");
97 }
98 }
99 else {
100 recordError("QuitPort provided is not within acceptable range: ("
101 + PortFinder.PORTS_RESERVED + " - " + PortFinder.MAX_PORT + "]" );
102 quitPort = -1;
103 }
104 }
105
106 // If the GSI is set to NOT autoenter/autostart the server, then write url=URL_PENDING out to the file.
107 // When the user finally presses the Enter Library button and so has started up the server, the correct
108 // url will be written out to the configfile.
109 if(config_properties.getProperty(BaseServer.Property.AUTOSTART, "").equals("0")) {//if(configfile.endsWith("llssite.cfg")) {
110 if(config_properties.getProperty("url") == null) {
111 config_properties.setProperty("url", URL_PENDING);
112 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
113 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
114 scriptReadWrite.replaceOrAddLine(fileLines, "url", URL_PENDING, true);
115 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
116 }
117 }
118
119 autoStart();
120 }
121
122 // Prepare the log4j.properties for GS2
123 protected void initLogger() {
124
125 String libjavaFolder = gsdl_home+File.separator+"lib"+File.separator+"java"+File.separator;
126 File propsFile = new File(libjavaFolder+"log4j.properties");
127
128 // create it from the template file log4j.properties.in
129 if(!propsFile.exists()) {
130 try {
131 // need to set gsdl2.home property's value to be gsdl_home,
132 // so that the location of the log files gets resolved correctly
133
134 // load the template log4j.properties.in file into logProps
135 FileInputStream infile = new FileInputStream(new File(libjavaFolder+"log4j.properties.in"));
136 if(infile != null) {
137 Properties logProps = new Properties();
138 logProps.load(infile);
139 infile.close();
140
141 // set gsdl3.home to gsdl_home
142 logProps.setProperty("gsdl2.home", gsdl_home);
143
144 // write the customised properties out to a custom log4j.properties file
145 FileOutputStream outfile = new FileOutputStream(propsFile);
146 if(outfile != null) {
147 logProps.store(outfile, "Customised log4j.properties file");
148 outfile.close();
149 } else {
150 System.err.println("Could not store properties file " + propsFile + " for Server2.");
151 }
152 }
153 } catch(Exception e) {
154 System.err.println("Exception occurred when custom-configuring the logger for Server2.\n" + e);
155 }
156 }
157
158 // now configure the logger with the custom log4j.properties file
159 if(propsFile.exists()) {
160 PropertyConfigurator.configure(propsFile.getAbsolutePath());
161 } else {
162 System.err.println("Could not create properties file " + propsFile + " for Server2.");
163 }
164 }
165
166
167 protected int runTarget(String cmd)
168 {
169 RunMake runMake = new RunMake();
170 runMake.setTargetCmd(cmd);
171 runMake.run();
172 return runMake.getTargetState();
173 }
174
175 public String getBrowserURL() {
176 return libraryURL;
177 }
178
179 // works out the library URL again
180 public void reload() {
181 // default values, to be replaced with what's in gsdlsite.cfg
182 String host = "localhost";
183 String port = "80";
184 String gwcgi;
185 String httpprefix = "greenstone";
186 String suffix = "/cgi-bin/library.cgi";
187
188 // get the prefix from the gsdlsite.cfg and build.properties files
189 // (port number and servername)
190 try{
191 File gsdlsite_cfg = new File(gsdl_home + File.separator + "cgi-bin" + File.separator + "gsdlsite.cfg");
192 FileInputStream fin = new FileInputStream(gsdlsite_cfg);
193 Properties gsdlProperties = new Properties();
194 if(fin != null) {
195 gsdlProperties.load(fin);
196
197 gwcgi = gsdlProperties.getProperty("gwcgi");
198 if(gwcgi != null) {
199 suffix = gwcgi;
200 } else {
201 httpprefix = gsdlProperties.getProperty("httpprefix", httpprefix);
202 suffix = httpprefix + suffix;
203 }
204 fin.close();
205 } else {
206 recordError("Could not open gsdlsite_cfg for reading, using default library prefix.");
207 }
208 //reloadConfigProperties();
209 port = config_properties.getProperty("portnumber", port);
210 } catch(Exception e) {
211 recordError("Exception trying to load properties from gsdlsite_cfg. Using default library prefix.", e);
212 suffix = httpprefix + suffix;
213 }
214
215 libraryURL = "http://" + host + ":" + port + suffix;
216 }
217
218 public void reloadConfigProperties() {
219 super.reloadConfigProperties();
220
221 // make sure the port is okay, otherwise find another port
222 // first choice is port 80, second choice starts at 8282
223 String port = config_properties.getProperty("portnumber", "80");
224 int portDefault = 8282;
225 try {
226 int portNum = Integer.parseInt(port);
227 boolean verbose = true;
228 if(!PortFinder.isPortAvailable(portNum, verbose)) { // first time, print any Port Unavailable messages
229
230 PortFinder portFinder = new PortFinder(portDefault, 101);
231 // Search for a free port silently from now on--don't want more
232 // messages saying that a port could not be found...
233 portNum = portFinder.findPortInRange(!verbose);
234
235 if (portNum == -1) {
236 // If we've still not found a free port, do we try the default port again?
237 System.err.println("No free port found. Going to try on " + portDefault + " anyway.");
238 port = Integer.toString(portDefault);
239 } else {
240 port = Integer.toString(portNum);
241 }
242 config_properties.setProperty("portnumber", port); // store the correct port
243
244 // write this updated port to the config file, since the configure target uses the file to run
245 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
246 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
247 scriptReadWrite.replaceOrAddLine(fileLines, "portnumber", port, false); // write the correct port
248 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
249
250 configure_required_ = true;
251 System.err.println("Running server on port " + port + ".");
252 }
253 } catch (Exception e) {
254 recordError("Exception in Server2.reload(): " + e.getMessage());
255 port = Integer.toString(portDefault);
256 }
257
258 }
259
260
261 // About to stop the webserver
262 // Custom GS2 action: remove the url property from the config file
263 protected void preStop() {
264 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
265 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
266
267 // Remove the url=... line, start searching from the end
268 boolean done = false;
269 for (int i = fileLines.size()-1; i >= 0 && !done; i--) {
270 String line = ((String) fileLines.get(i)).trim();
271 if(line.startsWith("url=")) {
272 fileLines.remove(i);
273 done = true;
274 }
275 }
276 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
277 }
278
279 // Called when the URL has been changed (called after a reload() and starting the server).
280 // By the time we get here, reload() would already have been called and have set
281 // both the port and worked out libraryURL
282 // This method needs to write the URL to the configfile since things should work
283 // like GS2's Local Lib Server for Windows
284 protected void postStart() {
285
286 URL libURL = null;
287 try {
288 libURL = new URL(libraryURL);
289 } catch (Exception e) {
290 recordError("Unable to convert library URL string into a valid URL, Server2.java." + e);
291 }
292
293 // 1. Test that the server is running at the libraryURL before writing it out to glisite.cfg/configfile
294 // A quick test involves opening a connection to get the home page for this collection
295 if(libURL != null && !libraryURL.equals(URL_PENDING)) {
296
297 boolean ready = false;
298 for(int i = 0; i < WAITING_TIME && !ready; i++) {
299 try {
300 libURL.openConnection();
301 //URLConnection connection = new URL(libraryURL).openConnection();
302 //connection.getContent();
303 ready = true;
304 recordSuccess("Try connecting to server on url: '" + libraryURL + "'");
305 } catch (IOException bad_url_connection) {
306 // keep looping
307 recordSuccess("NOT YET CONNECTED. Waiting to try again...");
308 try {
309 Thread.sleep(1000);
310 } catch (InterruptedException ie) {
311 ready = true;
312 recordError("Unexpected: got an InterruptedException in sleeping thread, Server2.java." + ie);
313 }
314 } catch (Exception e) {
315 ready = true;
316 recordError("Got an Exception while waiting for the connection to become live, Server2.java." + e);
317 }
318 }
319 }
320
321 // 2. Now write the URL to the config file
322 String port = config_properties.getProperty("portnumber");
323
324 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
325 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
326 scriptReadWrite.replaceOrAddLine(fileLines, "url", libraryURL, true);
327 scriptReadWrite.replaceOrAddLine(fileLines, "portnumber", port, false); // write the correct port
328 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
329 }
330
331
332 public static void main (String[] args)
333 {
334 if ((args.length < 1) || (args.length > 4)) {
335 System.err.println(
336 "Usage: java org.greenstone.server.Server2 <gsdl2-home-dir> [lang] [--config=configfile] [--quitport=portNum]");
337 System.exit(1);
338 }
339
340 String gsdl2_home = args[0];
341 File gsdl2_dir = new File(gsdl2_home);
342 if (!gsdl2_dir.isDirectory()) {
343 System.err.println("gsdl-home-dir directory does not exist!");
344 System.exit(1);
345 }
346
347 String lang = (args.length>=2) ? args[1] : "en";
348
349 // if no config file is given, then the following defaults to llssite.cfg
350 String configfile = (args.length>=3 && args[2].startsWith("--config=")) ? args[2] : gsdl2_home+File.separator+"llssite.cfg";
351 int equalSign = configfile.indexOf('=');
352 if(equalSign != -1) {
353 configfile = configfile.substring(equalSign+1);
354 }
355
356 String quitport = (args.length == 4 && args[3].startsWith("--quitport=")) ? args[3] : "";
357 equalSign = quitport.indexOf('=');
358 int port = -1;
359 if(equalSign != -1) {
360 try {
361 quitport = quitport.substring(equalSign+1);
362 port = Integer.parseInt(quitport);
363 } catch(Exception e) { // parse fails
364 System.err.println("Port must be numeric. Continuing without it.");
365 }
366 }
367
368 //System.err.println("Running server with config file: " + configfile);
369
370 new Server2(gsdl2_home, lang, configfile, port);
371 }
372}
Note: See TracBrowser for help on using the repository browser.