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

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

Changes to Server.jar files and affected files to add address_resolution options so that the GSI dialog for GS2 looks and behaves more like server.exe.

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 (port number and servername)
189 try{
190 File gsdlsite_cfg = new File(gsdl_home + File.separator + "cgi-bin" + File.separator + "gsdlsite.cfg");
191 FileInputStream fin = new FileInputStream(gsdlsite_cfg);
192 Properties gsdlProperties = new Properties();
193 if(fin != null) {
194 gsdlProperties.load(fin);
195
196 gwcgi = gsdlProperties.getProperty("gwcgi");
197 if(gwcgi != null) {
198 suffix = gwcgi;
199 } else {
200 httpprefix = gsdlProperties.getProperty("httpprefix", httpprefix);
201 suffix = httpprefix + suffix;
202 }
203 fin.close();
204 } else {
205 recordError("Could not open gsdlsite_cfg for reading, using default library prefix.");
206 }
207 //reloadConfigProperties();
208 port = config_properties.getProperty("portnumber", port);
209 host = config_properties.getProperty("host", host);
210
211 } catch(Exception e) {
212 recordError("Exception trying to load properties from gsdlsite_cfg. Using default library prefix.", e);
213 suffix = httpprefix + suffix;
214 }
215
216 libraryURL = "http://" + host + ":" + port + suffix;
217 }
218
219 public void reloadConfigProperties() {
220 super.reloadConfigProperties();
221
222 // make sure the port is okay, otherwise find another port
223 // first choice is port 80, second choice starts at 8282
224 String port = config_properties.getProperty("portnumber", "80");
225 int portDefault = 8282;
226 try {
227 int portNum = Integer.parseInt(port);
228 boolean verbose = true;
229 if(!PortFinder.isPortAvailable(portNum, verbose)) { // first time, print any Port Unavailable messages
230
231 PortFinder portFinder = new PortFinder(portDefault, 101);
232 // Search for a free port silently from now on--don't want more
233 // messages saying that a port could not be found...
234 portNum = portFinder.findPortInRange(!verbose);
235
236 if (portNum == -1) {
237 // If we've still not found a free port, do we try the default port again?
238 System.err.println("No free port found. Going to try on " + portDefault + " anyway.");
239 port = Integer.toString(portDefault);
240 } else {
241 port = Integer.toString(portNum);
242 }
243 config_properties.setProperty("portnumber", port); // store the correct port
244
245 // write this updated port to the config file, since the configure target uses the file to run
246 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
247 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
248 scriptReadWrite.replaceOrAddLine(fileLines, "portnumber", port, false); // write the correct port
249 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
250
251 configure_required_ = true;
252 System.err.println("Running server on port " + port + ".");
253 }
254 } catch (Exception e) {
255 recordError("Exception in Server2.reload(): " + e.getMessage());
256 port = Integer.toString(portDefault);
257 }
258
259 }
260
261
262 // About to stop the webserver
263 // Custom GS2 action: remove the url property from the config file
264 protected void preStop() {
265 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
266 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
267
268 // Remove the url=... line, start searching from the end
269 boolean done = false;
270 for (int i = fileLines.size()-1; i >= 0 && !done; i--) {
271 String line = ((String) fileLines.get(i)).trim();
272 if(line.startsWith("url=")) {
273 fileLines.remove(i);
274 done = true;
275 }
276 }
277 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
278 }
279
280 // Called when the URL has been changed (called after a reload() and starting the server).
281 // By the time we get here, reload() would already have been called and have set
282 // both the port and worked out libraryURL
283 // This method needs to write the URL to the configfile since things should work
284 // like GS2's Local Lib Server for Windows
285 protected void postStart() {
286
287 URL libURL = null;
288 try {
289 libURL = new URL(libraryURL);
290 } catch (Exception e) {
291 recordError("Unable to convert library URL string into a valid URL, Server2.java." + e);
292 }
293
294 // 1. Test that the server is running at the libraryURL before writing it out to glisite.cfg/configfile
295 // A quick test involves opening a connection to get the home page for this collection
296 if(libURL != null && !libraryURL.equals(URL_PENDING)) {
297
298 boolean ready = false;
299 for(int i = 0; i < WAITING_TIME && !ready; i++) {
300 try {
301 libURL.openConnection();
302 //URLConnection connection = new URL(libraryURL).openConnection();
303 //connection.getContent();
304 ready = true;
305 recordSuccess("Try connecting to server on url: '" + libraryURL + "'");
306 } catch (IOException bad_url_connection) {
307 // keep looping
308 recordSuccess("NOT YET CONNECTED. Waiting to try again...");
309 try {
310 Thread.sleep(1000);
311 } catch (InterruptedException ie) {
312 ready = true;
313 recordError("Unexpected: got an InterruptedException in sleeping thread, Server2.java." + ie);
314 }
315 } catch (Exception e) {
316 ready = true;
317 recordError("Got an Exception while waiting for the connection to become live, Server2.java." + e);
318 }
319 }
320 }
321
322 // 2. Now write the URL to the config file
323 String port = config_properties.getProperty("portnumber");
324
325 ScriptReadWrite scriptReadWrite = new ScriptReadWrite();
326 ArrayList fileLines = scriptReadWrite.readInFile(BaseServer.config_properties_file);
327 scriptReadWrite.replaceOrAddLine(fileLines, "url", libraryURL, true);
328 scriptReadWrite.replaceOrAddLine(fileLines, "portnumber", port, false); // write the correct port
329 scriptReadWrite.writeOutFile(config_properties_file, fileLines);
330 }
331
332
333 public static void main (String[] args)
334 {
335 if ((args.length < 1) || (args.length > 4)) {
336 System.err.println(
337 "Usage: java org.greenstone.server.Server2 <gsdl2-home-dir> [lang] [--config=configfile] [--quitport=portNum]");
338 System.exit(1);
339 }
340
341 String gsdl2_home = args[0];
342 File gsdl2_dir = new File(gsdl2_home);
343 if (!gsdl2_dir.isDirectory()) {
344 System.err.println("gsdl-home-dir directory does not exist!");
345 System.exit(1);
346 }
347
348 String lang = (args.length>=2) ? args[1] : "en";
349
350 // if no config file is given, then the following defaults to llssite.cfg
351 String configfile = (args.length>=3 && args[2].startsWith("--config=")) ? args[2] : gsdl2_home+File.separator+"llssite.cfg";
352 int equalSign = configfile.indexOf('=');
353 if(equalSign != -1) {
354 configfile = configfile.substring(equalSign+1);
355 }
356
357 String quitport = (args.length == 4 && args[3].startsWith("--quitport=")) ? args[3] : "";
358 equalSign = quitport.indexOf('=');
359 int port = -1;
360 if(equalSign != -1) {
361 try {
362 quitport = quitport.substring(equalSign+1);
363 port = Integer.parseInt(quitport);
364 } catch(Exception e) { // parse fails
365 System.err.println("Port must be numeric. Continuing without it.");
366 }
367 }
368
369 //System.err.println("Running server with config file: " + configfile);
370
371 new Server2(gsdl2_home, lang, configfile, port);
372 }
373}
Note: See TracBrowser for help on using the repository browser.