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

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

Waiting time for checking whether the server has started up already has been changed from 60s to 10s. (Tested.)

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