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

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

Rearranging the code that checks for whether a quitport is provided and if so whether it is assignable.

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