3 * Copyright (C) 2014 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.taxeditor
.httpinvoker
;
12 import java
.io
.BufferedReader
;
13 import java
.io
.IOException
;
14 import java
.io
.InputStreamReader
;
15 import java
.net
.Socket
;
17 import javax
.sql
.DataSource
;
19 import org
.apache
.log4j
.Level
;
20 import org
.apache
.log4j
.Logger
;
21 import org
.springframework
.core
.io
.ClassPathResource
;
22 import org
.springframework
.core
.io
.Resource
;
23 import org
.unitils
.database
.annotations
.TestDataSource
;
25 import eu
.etaxonomy
.taxeditor
.remoting
.server
.CDMServerException
;
26 import eu
.etaxonomy
.taxeditor
.remoting
.source
.CdmRemoteSourceBase
;
30 * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
31 * This is done by launching a jetty instance (using jetty-runner) as an
32 * executed process. The choice of the external process over a more
33 * preferable 'embedded jetty' instance is due to problems arising from the
34 * class loading of classes (e.g. from hibernate core) which are needed
35 * for both the webapp as well as the remoting client.
42 public class CDMServer
{
44 public static final Logger logger
= Logger
.getLogger(CDMServer
.class);
47 protected DataSource dataSource
;
49 private final String name
= "default";
50 private final String host
= "127.0.0.1";
51 private final int port
= 9090;
52 private final int stopPort
= 9191;
53 private final String stopKey
= "jetty-cdm-server";
54 private final String contextPath
= "";
56 private boolean keepServerRunning
= false;
58 public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE
=
59 new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
61 public static final Resource DEFAULT_JETTY_CONFIG_RESOURCE
=
62 new ClassPathResource("/etc/jetty/jetty.xml");
64 public static final Resource DEFAULT_JETTY_TEMP_RESOURCE
=
65 new ClassPathResource("/etc/jetty/temp");
67 public static final Resource DEFAULT_JETTY_TEMP_WAR_LIB_RESOURCE
=
68 new ClassPathResource("/etc/jetty/temp/webapp/WEB-INF/lib");
70 public static final Resource DEFAULT_DATASOURCE_FILE
=
71 new ClassPathResource("datasources.xml");
73 public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE
=
74 new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
76 public static final Resource DEFAULT_JETTY_RESOURCE
=
77 new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
81 private static CDMServer cdmServer
= null;
82 private static CDMServerException cdmse
= null;
84 private void CDMServer() {
85 logger
.setLevel(Level
.INFO
);
88 public static CDMServer
getInstance() {
89 if(cdmServer
== null) {
90 cdmServer
= new CDMServer();
95 public String
getName() {
99 public String
getHost() {
103 public int getPort() {
107 public String
getContextPath() {
111 public boolean getKeepServerRunning() {
112 return keepServerRunning
;
115 public void setKeepServerRunning(boolean keepServerRunning
) {
116 this.keepServerRunning
= keepServerRunning
;
119 public static boolean isRunningInEclipse() {
120 return (System
.getProperty("sun.java.command") != null &&
121 System
.getProperty("sun.java.command").startsWith("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner"));
124 private String
getVMArgs() throws IOException
{
125 StringBuilder sb
= new StringBuilder();
126 sb
.append(" -Dspring.profiles.active=remoting");
127 sb
.append(" -Dcdm.beanDefinitionFile=" + DEFAULT_DATASOURCE_FILE
.getFile().getAbsolutePath());
128 sb
.append(" -Dcdm.datasource=cdmTest");
129 return sb
.toString();
132 private String
getStartServerArgs() {
133 StringBuilder sb
= new StringBuilder();
134 sb
.append(" --port ");
136 return sb
.toString();
139 private String
getStopServerSettings() {
140 StringBuilder sb
= new StringBuilder();
141 sb
.append(" --stop-port ");
143 sb
.append(" --stop-key ");
145 return sb
.toString();
148 private String
getStopServerArgs() {
149 StringBuilder sb
= new StringBuilder();
150 sb
.append(" STOP.PORT=");
152 sb
.append(" STOP.KEY=");
154 return sb
.toString();
157 public void start() throws CDMServerException
{
160 * First check if the CDM server responds to a service request, which implies that
161 * the server has started properly. If no response is received then check if the
162 * server is listening on specific host / port, which implies that the server
163 * has started but incorrectly, in which case we try to force stop it (if we can)
164 * and start a new server.
167 logger
.info("[CDM-Server] Server already running @ " + host
+ ":" + port
);
169 } else if (isAvailable(1)){
170 logger
.info("[CDM-Server] Server available, but not started correctly @ " + host
+ ":" + port
);
171 logger
.info("[CDM-Server] .... trying to force stop server @ " + host
+ ":" + port
);
174 } catch (Exception e
) {
175 throw new CDMServerException("CDM Server could not be stopped : " + e
.getMessage());
179 Thread t
= new Thread() {
182 StringBuffer output
= new StringBuffer();
185 String command
= "java "
188 + DEFAULT_JETTY_RUNNER_RESOURCE
.getFile().getAbsolutePath()
189 + getStartServerArgs()
190 + getStopServerSettings()
192 + DEFAULT_CDM_WEBAPP_RESOURCE
.getFile().getAbsolutePath();
193 logger
.info("[CDM-Server] Starting server with Command : " + command
);
194 p
= Runtime
.getRuntime().exec(command
);
196 BufferedReader reader
=
197 new BufferedReader(new InputStreamReader(p
.getInputStream()));
200 while ((line
= reader
.readLine())!= null) {
201 logger
.info("[CDM-Server] Start : " + line
);
204 } catch (Exception e
) {
206 cdmse
= new CDMServerException(e
);
217 logger
.info("[CDM-Server] Started Server @ " + host
+ ":" + port
);
219 logger
.info("[CDM-Server] Server not started within given interval");
220 // making sure to kill server if it is not started correctly
223 } catch (Exception e
) {
224 throw new CDMServerException("CDM Server could not be stopped : " + e
.getMessage());
226 throw new CDMServerException("CDM Server not started : ");
231 public boolean isAvailable(int checkingIntervals
) throws CDMServerException
{
232 int intervalsCount
= 0;
235 Socket s
= new Socket(host
, port
);
236 logger
.info("[CDM-Server] Available @ " + host
+ ":" + port
);
238 } catch (IOException ioe
) {
243 } catch (InterruptedException ie
) {
244 throw new CDMServerException("Error checking CDM Server status", ie
);
247 } while (intervalsCount
< checkingIntervals
);
252 public boolean isStopped(int checkingIntervals
) throws CDMServerException
{
253 int intervalsCount
= 0;
256 Socket s
= new Socket(host
, port
);
257 } catch (IOException ioe
) {
262 } catch (InterruptedException ie
) {
263 throw new CDMServerException("Error checking CDM Server status", ie
);
266 } while (intervalsCount
< checkingIntervals
);
271 public boolean isRunning(int checkingIntervals
) throws CDMServerException
{
272 CdmRemoteSourceBase crsb
= new CdmRemoteSourceBase("local-cdm-server",
277 int intervalsCount
= 0;
283 boolean check
= crsb
.checkConnection();
285 logger
.info("[CDM-Server] Running @ " + host
+ ":" + port
);
288 } catch (Exception e
) {
293 } catch (InterruptedException ie
) {
294 throw new CDMServerException("Error checking CDM Server status", ie
);
297 } while (intervalsCount
< checkingIntervals
);
301 public void stop() throws Exception
{
304 public void stop(boolean force
) throws Exception
{
307 if(!getInstance().isAvailable(1)) {
308 logger
.info("[CDM-Server] Server already stopped @ " + host
+ ":" + port
);
312 if(getInstance().getKeepServerRunning()) {
313 logger
.info("[CDM-Server] Server @ " + host
+ ":" + port
+ " is set to keep running");
317 Thread t
= new Thread() {
320 StringBuffer output
= new StringBuffer();
323 String command
= "java -jar " + DEFAULT_JETTY_RESOURCE
.getFile().getAbsolutePath()
324 + getStopServerArgs() + " --stop ";
325 logger
.info("[CDM-Server] Stop Command : " + command
);
326 p
= Runtime
.getRuntime().exec(command
);
328 BufferedReader reader
=
329 new BufferedReader(new InputStreamReader(p
.getInputStream()));
331 while ((line
= reader
.readLine())!= null) {
332 logger
.info("CDM-Server Stop : " + line
+ "\n");
334 } catch (Exception e
) {
345 logger
.info("[CDM-Server] Stopped Server @ " + host
+ ":" + port
);
347 logger
.info("[CDM-Server] Could not stop @ " + host
+ ":" + port
+ ". Please kill it manually");