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
;
18 import javax
.sql
.DataSource
;
20 import org
.apache
.log4j
.Level
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.springframework
.core
.io
.ClassPathResource
;
23 import org
.springframework
.core
.io
.Resource
;
24 import org
.unitils
.database
.annotations
.TestDataSource
;
25 import org
.unitils
.spring
.annotation
.SpringApplicationContext
;
27 import eu
.etaxonomy
.cdm
.remote
.CdmRemoteSourceBase
;
28 import eu
.etaxonomy
.taxeditor
.exception
.CDMServerException
;
32 * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
33 * This is done by launching a jetty instance (using jetty-runner) as an
34 * executed process. The choice of the external process over a more
35 * preferable 'embedded jetty' instance is due to problems arising from the
36 * class loading of classes (e.g. from hibernate core) which are needed
37 * for both the webapp as well as the remoting client.
44 public class CDMServer
{
46 public static final Logger logger
= Logger
.getLogger(CDMServer
.class);
49 protected DataSource dataSource
;
51 private final String name
= "default";
52 private final String host
= "127.0.0.1";
53 private final int port
= 9090;
54 private final int stopPort
= 9191;
55 private final String stopKey
= "jetty-cdm-server";
56 private final String contextPath
= "";
58 private boolean keepServerRunning
= false;
60 public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE
=
61 new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
63 public static final Resource DEFAULT_JETTY_CONFIG_RESOURCE
=
64 new ClassPathResource("/etc/jetty/jetty.xml");
66 public static final Resource DEFAULT_JETTY_TEMP_RESOURCE
=
67 new ClassPathResource("/etc/jetty/temp");
69 public static final Resource DEFAULT_JETTY_TEMP_WAR_LIB_RESOURCE
=
70 new ClassPathResource("/etc/jetty/temp/webapp/WEB-INF/lib");
72 public static final Resource DEFAULT_DATASOURCE_FILE
=
73 new ClassPathResource("datasources.xml");
75 public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE
=
76 new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
78 public static final Resource DEFAULT_JETTY_RESOURCE
=
79 new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
83 private static CDMServer cdmServer
= null;
84 private static CDMServerException cdmse
= null;
86 private void CDMServer() {
87 logger
.setLevel(Level
.INFO
);
90 public static CDMServer
getInstance() {
91 if(cdmServer
== null) {
92 cdmServer
= new CDMServer();
97 public String
getName() {
101 public String
getHost() {
105 public int getPort() {
109 public String
getContextPath() {
113 public boolean getKeepServerRunning() {
114 return keepServerRunning
;
117 public void setKeepServerRunning(boolean keepServerRunning
) {
118 this.keepServerRunning
= keepServerRunning
;
121 public static boolean isRunningInEclipse() {
122 return (System
.getProperty("sun.java.command") != null &&
123 System
.getProperty("sun.java.command").startsWith("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner"));
126 private String
getVMArgs() throws IOException
{
127 StringBuilder sb
= new StringBuilder();
128 sb
.append(" -Dspring.profiles.active=remoting");
129 sb
.append(" -Dcdm.beanDefinitionFile=" + DEFAULT_DATASOURCE_FILE
.getFile().getAbsolutePath());
130 sb
.append(" -Dcdm.datasource=cdmTest");
131 return sb
.toString();
134 private String
getStartServerArgs() {
135 StringBuilder sb
= new StringBuilder();
136 sb
.append(" --port ");
138 return sb
.toString();
141 private String
getStopServerSettings() {
142 StringBuilder sb
= new StringBuilder();
143 sb
.append(" --stop-port ");
145 sb
.append(" --stop-key ");
147 return sb
.toString();
150 private String
getStopServerArgs() {
151 StringBuilder sb
= new StringBuilder();
152 sb
.append(" STOP.PORT=");
154 sb
.append(" STOP.KEY=");
156 return sb
.toString();
159 public void start() throws CDMServerException
{
162 * First check if the CDM server responds to a service request, which implies that
163 * the server has started properly. If no response is received then check if the
164 * server is listening on specific host / port, which implies that the server
165 * has started but incorrectly, in which case we try to force stop it (if we can)
166 * and start a new server.
169 logger
.info("[CDM-Server] Server already running @ " + host
+ ":" + port
);
171 } else if (isAvailable(1)){
172 logger
.info("[CDM-Server] Server available, but not started correctly @ " + host
+ ":" + port
);
173 logger
.info("[CDM-Server] .... trying to force stop server @ " + host
+ ":" + port
);
176 } catch (Exception e
) {
177 throw new CDMServerException("CDM Server could not be stopped : " + e
.getMessage());
181 Thread t
= new Thread() {
184 StringBuffer output
= new StringBuffer();
187 String command
= "java "
190 + DEFAULT_JETTY_RUNNER_RESOURCE
.getFile().getAbsolutePath()
191 + getStartServerArgs()
192 + getStopServerSettings()
194 + DEFAULT_CDM_WEBAPP_RESOURCE
.getFile().getAbsolutePath();
195 logger
.info("[CDM-Server] Starting server with Command : " + command
);
196 p
= Runtime
.getRuntime().exec(command
);
198 BufferedReader reader
=
199 new BufferedReader(new InputStreamReader(p
.getInputStream()));
202 while ((line
= reader
.readLine())!= null) {
203 logger
.info("[CDM-Server] Start : " + line
);
206 } catch (Exception e
) {
208 cdmse
= new CDMServerException(e
);
219 logger
.info("[CDM-Server] Started Server @ " + host
+ ":" + port
);
221 logger
.info("[CDM-Server] Server not started within given interval");
222 // making sure to kill server if it is not started correctly
225 } catch (Exception e
) {
226 throw new CDMServerException("CDM Server could not be stopped : " + e
.getMessage());
228 throw new CDMServerException("CDM Server not started : ");
233 public boolean isAvailable(int checkingIntervals
) throws CDMServerException
{
234 int intervalsCount
= 0;
237 Socket s
= new Socket(host
, port
);
238 logger
.info("[CDM-Server] Available @ " + host
+ ":" + port
);
240 } catch (IOException ioe
) {
245 } catch (InterruptedException ie
) {
246 throw new CDMServerException("Error checking CDM Server status", ie
);
249 } while (intervalsCount
< checkingIntervals
);
254 public boolean isStopped(int checkingIntervals
) throws CDMServerException
{
255 int intervalsCount
= 0;
258 Socket s
= new Socket(host
, port
);
259 } catch (IOException ioe
) {
260 logger
.info("[CDM-Server] Stopped @ " + host
+ ":" + port
);
265 } catch (InterruptedException ie
) {
266 throw new CDMServerException("Error checking CDM Server status", ie
);
269 } while (intervalsCount
< checkingIntervals
);
274 public boolean isRunning(int checkingIntervals
) throws CDMServerException
{
275 CdmRemoteSourceBase crsb
= new CdmRemoteSourceBase("local-cdm-server",
280 int intervalsCount
= 0;
286 if(crsb
.checkConnection()) {
287 logger
.info("[CDM-Server] Running @ " + host
+ ":" + port
);
290 } catch (Exception e
) {
294 } catch (InterruptedException ie
) {
295 throw new CDMServerException("Error checking CDM Server status", ie
);
298 } while (intervalsCount
< checkingIntervals
);
302 public void stop() throws Exception
{
305 public void stop(boolean force
) throws Exception
{
308 if(!getInstance().isAvailable(1)) {
309 logger
.info("[CDM-Server] Server already stopped @ " + host
+ ":" + port
);
313 if(getInstance().getKeepServerRunning()) {
314 logger
.info("[CDM-Server] Server @ " + host
+ ":" + port
+ " is set to keep running");
318 Thread t
= new Thread() {
321 StringBuffer output
= new StringBuffer();
324 String command
= "java -jar " + DEFAULT_JETTY_RESOURCE
.getFile().getAbsolutePath()
325 + getStopServerArgs() + " --stop ";
326 logger
.info("[CDM-Server] Stop Command : " + command
);
327 p
= Runtime
.getRuntime().exec(command
);
329 BufferedReader reader
=
330 new BufferedReader(new InputStreamReader(p
.getInputStream()));
332 while ((line
= reader
.readLine())!= null) {
333 logger
.info("CDM-Server Stop : " + line
+ "\n");
335 } catch (Exception e
) {
346 logger
.info("[CDM-Server] Stopped Server @ " + host
+ ":" + port
);
348 logger
.info("[CDM-Server] Could not stop @ " + host
+ ":" + port
+ ". Please kill it manually");