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

Last change on this file since 23251 was 23251, checked in by sjm84, 13 years ago

The localhost and hostname did not work on the Ubuntu here, but should have been working. It does work if hostname and localhost are written into the httpd.conf file. To get it to do that, made changes to the server.jar code, and so also server.jar, as well as GS2 scripts and config files (httpd.conf.in files for linux and windows), llssite.cfg.in, glisite.cfg.in and gsicontrol.bat and .sh

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