KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > server > ServerLock


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.server;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.net.InetSocketAddress JavaDoc;
31 import java.net.Socket JavaDoc;
32 import java.net.SocketAddress JavaDoc;
33 import java.util.StringTokenizer JavaDoc;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38 import com.sslexplorer.boot.ContextHolder;
39 import com.sslexplorer.boot.Util;
40
41 /**
42  * Used to determine if SSL-Explorer (or some other server) is already running
43  * under a different runtime. The check also determines if the already running
44  * the installation wizard.
45  * <p>
46  * This mechanism also provides a way for the server to be shutdown use a
47  * scrip. Once created, the lock file is watched and if it changes to contain
48  * the text "shutdown" then the server will be shutdown.
49  *
50  * @author Brett Smith <brett@3sp.com>
51  */

52 public class ServerLock {
53
54     final static Log log = LogFactory.getLog(ServerLock.class);
55
56     private File JavaDoc lockFile;
57     private boolean locked;
58     private boolean setup;
59     private int port;
60     private String JavaDoc bindAddress;
61     private boolean started;
62     private long lastLockChange;
63
64     /**
65      * Constructor. The lock will be searched for, and if a service is known to
66      * be already running an exception is thrown.
67      *
68      * @param bindAddress address of interface server is bound to
69      * @throws IOException if the service is already running
70      *
71      */

72     public ServerLock(String JavaDoc bindAddress) throws IOException JavaDoc {
73
74         this.bindAddress = bindAddress;
75         lockFile = new File JavaDoc(ContextHolder.getContext().getTempDirectory(), "sslexplorer.run");
76
77         /*
78          * Check that SSL Explorer is not already running using file locks. If
79          * the file exists but is not locked, then this may be have been an
80          * unclean shutdown
81          */

82         if (lockFile.exists()) {
83             FileInputStream JavaDoc lockIn = null;
84             try {
85                 lockIn = new FileInputStream JavaDoc(lockFile);
86                 BufferedReader JavaDoc br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(lockIn));
87                 String JavaDoc r = br.readLine();
88                 if (r != null && !r.equals("")) {
89                     try {
90                         if(!r.equals("shutdown") || r.equals("restart")) {
91                             StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(r, ":");
92                             setup = "true".equals(t.nextToken());
93                             port = Integer.parseInt(t.nextToken());
94                             checkStatus();
95                         }
96                     } catch (Exception JavaDoc e) {
97                         System.err.println("Could not parse lock file.");
98                         e.printStackTrace();
99                     }
100                 }
101             } finally {
102                 Util.closeStream(lockIn);
103             }
104         }
105     }
106
107     /**
108      * Get if a service is already running.
109      *
110      * @return server is locked
111      */

112     public boolean isLocked() {
113         return locked;
114     }
115
116     /**
117      * Should be called when the service starts. This checks if a service is
118      * already running, and if not creates the lock so future instances know.
119      *
120      * @param port port the service is running on
121      * @throws IOException
122      */

123     public void start(int port) throws IOException JavaDoc {
124         this.port = port;
125         this.setup = ContextHolder.getContext().isSetupMode();
126
127         /*
128          * Check whether there is already a listener on the port, this means we
129          * can throw a more meaningful exception than jetty does if a server
130          * other than SSL-Explorer is already running on this port
131          */

132         checkStatus();
133         if (locked) {
134             if (port == 443 || port == 8443) {
135                 throw new IOException JavaDoc("Some server other than SSL-Explorer is already running on port " + port + "."
136                                 + "Most web servers will run on this port by default, so check if you have such "
137                                 + "a service is installed (IIS, Apache or Tomcat for example). Either shutdown "
138                                 + "and disable the conflicting server, or if you wish to run both services "
139                                 + "concurrently, change the port number on which one listens.");
140             } else {
141                 throw new IOException JavaDoc("Some server other than SSL-Explorer is already running on port " + port + "."
142                                 + "Check which other services you have enabled that may be causing "
143                                 + "this conflict. Then, either disable the service, change the port on "
144                                 + "which it is listening or change the port on which SSL-Explorer listens.");
145
146             }
147         }
148
149         //
150
PrintWriter JavaDoc pw = new PrintWriter JavaDoc(new FileOutputStream JavaDoc(lockFile));
151         pw.println(ContextHolder.getContext().isSetupMode() + ":" + port);
152         pw.flush();
153         pw.close();
154         started = true;
155         
156         lastLockChange = lockFile.lastModified();
157         
158         /* Start watching the lock file, if it disappears then shut down the
159          * server
160          */

161         Thread JavaDoc t = new Thread JavaDoc("ServerLockMonitor") {
162             public void run() {
163                 while(true) {
164                     try {
165                         Thread.sleep(5000);
166                         if(lastLockChange != lockFile.lastModified()) {
167                             lastLockChange = lockFile.lastModified();
168                             if (log.isDebugEnabled())
169                                 log.debug("Lock file changed, examining");
170                             InputStream JavaDoc in = null;
171                             try {
172                                 in = new FileInputStream JavaDoc(lockFile);;
173                                 BufferedReader JavaDoc br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
174                                 String JavaDoc s = br.readLine();
175                                 Util.closeStream(in); // close so we can delete
176
if("shutdown".equals(s)) {
177                                     ContextHolder.getContext().shutdown(false);
178                                     break;
179                                 }
180                                 else if("restart".equals(s)) {
181                                     ContextHolder.getContext().shutdown(true);
182                                     break;
183                                 }
184                             }
185                             catch(IOException JavaDoc ioe) {
186                                 Util.closeStream(in);
187                                 throw ioe;
188                             }
189                         }
190                     }
191                     catch(Exception JavaDoc e) {
192                     }
193                 }
194             }
195         };
196         t.setDaemon(true);
197         t.setPriority(Thread.MIN_PRIORITY);
198         t.start();
199         
200
201     }
202
203     /**
204      * Get if this instance started and is running
205      *
206      * @return started
207      *
208      */

209     public boolean isStarted() {
210         return started;
211     }
212
213     /**
214      * Remove the lock and clean up. Should be called when the server shuts
215      * down.
216      */

217     public void stop() {
218         if (log.isInfoEnabled())
219             log.info("Removing lock");
220         lockFile.delete();
221         started = false;
222     }
223
224     /**
225      * Get if the currently running service is running the installation wizard.
226      *
227      * @return running installation wizard
228      */

229     public boolean isSetup() {
230         return setup;
231     }
232
233     /**
234      * Get the port the currently running service is running on
235      *
236      * @return port
237      */

238     public int getPort() {
239         return port;
240     }
241
242     private void checkStatus() {
243         Socket JavaDoc socket = null;
244         try {
245             int timeout = 5000; // 5 seconds
246
if (log.isInfoEnabled())
247                 log.info("Connecting to " + bindAddress + ":" + port + " to see if a server is already running.");
248             SocketAddress JavaDoc socketAddress = new InetSocketAddress JavaDoc(bindAddress, port);
249             socket = new Socket JavaDoc();
250             socket.connect(socketAddress, timeout);
251             locked = true;
252         } catch (Exception JavaDoc e) {
253             locked = false;
254         } finally {
255             if (socket != null) {
256                 try {
257                     socket.close();
258                 } catch (Exception JavaDoc e) {
259
260                 }
261             }
262         }
263     }
264
265 }
266
Popular Tags