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

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