- extended DnaQuality details view
[taxeditor.git] / eu.etaxonomy.taxeditor.remoting / src / test / java / eu / etaxonomy / taxeditor / httpinvoker / CDMServer.java
1 // $Id$
2 /**
3 * Copyright (C) 2014 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
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.
9 */
10 package eu.etaxonomy.taxeditor.httpinvoker;
11
12 import java.io.BufferedReader;
13 import java.io.IOException;
14 import java.io.InputStreamReader;
15 import java.net.Socket;
16
17
18 import javax.sql.DataSource;
19
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;
26
27 import eu.etaxonomy.cdm.remote.CdmRemoteSourceBase;
28 import eu.etaxonomy.taxeditor.exception.CDMServerException;
29
30 /**
31 *
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.
38 *
39 * @author cmathew
40 * @date 23 Sep 2014
41 *
42 */
43
44 public class CDMServer {
45
46 public static final Logger logger = Logger.getLogger(CDMServer.class);
47
48 @TestDataSource
49 protected DataSource dataSource;
50
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 = "";
57
58 private boolean keepServerRunning = false;
59
60 public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE =
61 new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
62
63 public static final Resource DEFAULT_JETTY_CONFIG_RESOURCE =
64 new ClassPathResource("/etc/jetty/jetty.xml");
65
66 public static final Resource DEFAULT_JETTY_TEMP_RESOURCE =
67 new ClassPathResource("/etc/jetty/temp");
68
69 public static final Resource DEFAULT_JETTY_TEMP_WAR_LIB_RESOURCE =
70 new ClassPathResource("/etc/jetty/temp/webapp/WEB-INF/lib");
71
72 public static final Resource DEFAULT_DATASOURCE_FILE =
73 new ClassPathResource("datasources.xml");
74
75 public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE =
76 new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
77
78 public static final Resource DEFAULT_JETTY_RESOURCE =
79 new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
80
81
82
83 private static CDMServer cdmServer = null;
84 private static CDMServerException cdmse = null;
85
86 private void CDMServer() {
87 logger.setLevel(Level.INFO);
88 }
89
90 public static CDMServer getInstance() {
91 if(cdmServer == null) {
92 cdmServer = new CDMServer();
93 }
94 return cdmServer;
95 }
96
97 public String getName() {
98 return name;
99 }
100
101 public String getHost() {
102 return host;
103 }
104
105 public int getPort() {
106 return port;
107 }
108
109 public String getContextPath() {
110 return contextPath;
111 }
112
113 public boolean getKeepServerRunning() {
114 return keepServerRunning;
115 }
116
117 public void setKeepServerRunning(boolean keepServerRunning) {
118 this.keepServerRunning = keepServerRunning;
119 }
120
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"));
124 }
125
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();
132 }
133
134 private String getStartServerArgs() {
135 StringBuilder sb = new StringBuilder();
136 sb.append(" --port ");
137 sb.append(port);
138 return sb.toString();
139 }
140
141 private String getStopServerSettings() {
142 StringBuilder sb = new StringBuilder();
143 sb.append(" --stop-port ");
144 sb.append(stopPort);
145 sb.append(" --stop-key ");
146 sb.append(stopKey);
147 return sb.toString();
148 }
149
150 private String getStopServerArgs() {
151 StringBuilder sb = new StringBuilder();
152 sb.append(" STOP.PORT=");
153 sb.append(stopPort);
154 sb.append(" STOP.KEY=");
155 sb.append(stopKey);
156 return sb.toString();
157 }
158
159 public void start() throws CDMServerException {
160
161 /**
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.
167 */
168 if(isRunning(1)) {
169 logger.info("[CDM-Server] Server already running @ " + host + ":" + port );
170 return;
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 );
174 try {
175 stop(true);
176 } catch (Exception e) {
177 throw new CDMServerException("CDM Server could not be stopped : " + e.getMessage());
178 }
179 }
180
181 Thread t = new Thread() {
182 @Override
183 public void run() {
184 StringBuffer output = new StringBuffer();
185 try{
186 Process p;
187 String command = "java "
188 + getVMArgs()
189 + " -jar "
190 + DEFAULT_JETTY_RUNNER_RESOURCE.getFile().getAbsolutePath()
191 + getStartServerArgs()
192 + getStopServerSettings()
193 + " "
194 + DEFAULT_CDM_WEBAPP_RESOURCE.getFile().getAbsolutePath();
195 logger.info("[CDM-Server] Starting server with Command : " + command);
196 p = Runtime.getRuntime().exec(command);
197
198 BufferedReader reader =
199 new BufferedReader(new InputStreamReader(p.getInputStream()));
200
201 String line = "";
202 while ((line = reader.readLine())!= null) {
203 logger.info("[CDM-Server] Start : " + line);
204 }
205
206 } catch (Exception e) {
207 e.printStackTrace();
208 cdmse = new CDMServerException(e);
209 }
210
211 }
212 };
213
214 t.setDaemon(true);
215 cdmse = null;
216 t.start();
217
218 if(isRunning(50)) {
219 logger.info("[CDM-Server] Started Server @ " + host + ":" + port );
220 } else {
221 logger.info("[CDM-Server] Server not started within given interval");
222 // making sure to kill server if it is not started correctly
223 try {
224 stop(true);
225 } catch (Exception e) {
226 throw new CDMServerException("CDM Server could not be stopped : " + e.getMessage());
227 }
228 throw new CDMServerException("CDM Server not started : ");
229 }
230
231 }
232
233 public boolean isAvailable(int checkingIntervals) throws CDMServerException {
234 int intervalsCount = 0;
235 do {
236 try {
237 Socket s = new Socket(host, port);
238 logger.info("[CDM-Server] Available @ " + host + ":" + port );
239 return true;
240 } catch (IOException ioe) {
241
242 }
243 try {
244 Thread.sleep(1000);
245 } catch (InterruptedException ie) {
246 throw new CDMServerException("Error checking CDM Server status", ie);
247 }
248 intervalsCount++;
249 } while (intervalsCount < checkingIntervals);
250
251 return false;
252 }
253
254 public boolean isStopped(int checkingIntervals) throws CDMServerException {
255 int intervalsCount = 0;
256 do {
257 try {
258 Socket s = new Socket(host, port);
259 } catch (IOException ioe) {
260 logger.info("[CDM-Server] Stopped @ " + host + ":" + port );
261 return true;
262 }
263 try {
264 Thread.sleep(1000);
265 } catch (InterruptedException ie) {
266 throw new CDMServerException("Error checking CDM Server status", ie);
267 }
268 intervalsCount++;
269 } while (intervalsCount < checkingIntervals);
270
271 return false;
272 }
273
274 public boolean isRunning(int checkingIntervals) throws CDMServerException {
275 CdmRemoteSourceBase crsb = new CdmRemoteSourceBase("local-cdm-server",
276 host,
277 port,
278 contextPath,
279 null);
280 int intervalsCount = 0;
281 do {
282 try {
283 if(cdmse != null) {
284 return false;
285 }
286 if(crsb.checkConnection()) {
287 logger.info("[CDM-Server] Running @ " + host + ":" + port );
288 return true;
289 }
290 } catch (Exception e) {
291 }
292 try {
293 Thread.sleep(1000);
294 } catch (InterruptedException ie) {
295 throw new CDMServerException("Error checking CDM Server status", ie);
296 }
297 intervalsCount++;
298 } while (intervalsCount < checkingIntervals);
299 return false;
300 }
301
302 public void stop() throws Exception {
303 stop(false);
304 }
305 public void stop(boolean force) throws Exception {
306
307 if(!force) {
308 if(!getInstance().isAvailable(1)) {
309 logger.info("[CDM-Server] Server already stopped @ " + host + ":" + port );
310 return;
311 }
312
313 if(getInstance().getKeepServerRunning()) {
314 logger.info("[CDM-Server] Server @ " + host + ":" + port + " is set to keep running");
315 return;
316 }
317 }
318 Thread t = new Thread() {
319 @Override
320 public void run() {
321 StringBuffer output = new StringBuffer();
322 try{
323 Process p;
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);
328 p.waitFor();
329 BufferedReader reader =
330 new BufferedReader(new InputStreamReader(p.getInputStream()));
331 String line = "";
332 while ((line = reader.readLine())!= null) {
333 logger.info("CDM-Server Stop : " + line + "\n");
334 }
335 } catch (Exception e) {
336 e.printStackTrace();
337 }
338
339 }
340 };
341
342 t.setDaemon(true);
343 t.start();
344
345 if(isStopped(5)) {
346 logger.info("[CDM-Server] Stopped Server @ " + host + ":" + port );
347 } else {
348 logger.info("[CDM-Server] Could not stop @ " + host + ":" + port + ". Please kill it manually");
349 }
350 }
351 }