fixed issues with resource loading for maven int tests
[taxeditor.git] / eu.etaxonomy.taxeditor.test / 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
16 import javax.management.InstanceNotFoundException;
17 import javax.management.MBeanException;
18 import javax.management.MBeanServerConnection;
19 import javax.management.MalformedObjectNameException;
20 import javax.management.ObjectName;
21 import javax.management.ReflectionException;
22 import javax.management.remote.JMXConnector;
23 import javax.management.remote.JMXConnectorFactory;
24 import javax.management.remote.JMXServiceURL;
25 import javax.sql.DataSource;
26
27 import org.apache.log4j.Logger;
28 import org.springframework.core.io.ClassPathResource;
29 import org.springframework.core.io.Resource;
30 import org.unitils.database.annotations.TestDataSource;
31
32 import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
33 import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSourceBase;
34
35 /**
36 *
37 * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
38 * This is done by launching a jetty instance (using jetty-runner) as an
39 * executed process. The choice of the external process over a more
40 * preferable 'embedded jetty' instance is due to problems arising from the
41 * class loading of classes (e.g. from hibernate core) which are needed
42 * for both the webapp as well as the remoting client.
43 *
44 * @author cmathew
45 * @date 23 Sep 2014
46 *
47 */
48
49 public class CDMServer {
50
51 public static final Logger logger = Logger.getLogger(CDMServer.class);
52
53 @TestDataSource
54 protected DataSource dataSource;
55
56 private final String name = "default";
57 private final String host = "127.0.0.1";
58 private int httpPort = 9090;
59 private int stopPort = 9191;
60 private String stopKey = "jetty-cdm-server";
61 private final String contextPath = "";
62
63 public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE =
64 new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
65
66 public static final Resource DEFAULT_DATASOURCE_FILE =
67 new ClassPathResource("datasources.xml");
68
69 public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE =
70 new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
71
72 public static final Resource DEFAULT_JETTY_RESOURCE =
73 new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
74
75 private static CDMServer cdmServer = null;
76 private static CDMServerException cdmse = null;
77
78 private boolean serverAlreadyRunning = false;
79
80 private void CDMServer() {}
81
82 public static CDMServer getInstance() {
83 if(cdmServer == null) {
84 cdmServer = new CDMServer();
85 }
86 return cdmServer;
87 }
88
89 public String getName() {
90 return name;
91 }
92
93 public String getHost() {
94 return host;
95 }
96
97 public int getPort() {
98 return httpPort;
99 }
100
101 public String getContextPath() {
102 return contextPath;
103 }
104
105 public void setHttpPort(int port) {
106 this.httpPort = port;
107 }
108
109 public void setStopPort(int stopPort) {
110 this.stopPort = stopPort;
111 }
112
113 public void setStopKey(String stopKey) {
114 this.stopKey = stopKey;
115 }
116
117
118 public static boolean isRunningInEclipse() {
119 return (System.getProperty("sun.java.command") != null &&
120 System.getProperty("sun.java.command").startsWith("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner"));
121 }
122
123 private String getVMArgs() throws IOException {
124 StringBuilder sb = new StringBuilder();
125 sb.append(" -Dspring.profiles.active=remoting");
126 sb.append(" -Dcdm.beanDefinitionFile=" + DEFAULT_DATASOURCE_FILE.getFile().getAbsolutePath());
127 sb.append(" -Dcdm.datasource=cdmTest");
128 return sb.toString();
129 }
130
131 private String getStartServerArgs() throws IOException {
132 StringBuilder sb = new StringBuilder();
133 sb.append(" --port " + httpPort);
134 return sb.toString();
135 }
136
137 private String getStopServerSettings() {
138 StringBuilder sb = new StringBuilder();
139 sb.append(" --stop-port ");
140 sb.append(stopPort);
141 sb.append(" --stop-key ");
142 sb.append(stopKey);
143 return sb.toString();
144 }
145
146 private String getStopServerArgs() {
147 StringBuilder sb = new StringBuilder();
148 sb.append(" STOP.PORT=");
149 sb.append(stopPort);
150 sb.append(" STOP.KEY=");
151 sb.append(stopKey);
152 return sb.toString();
153 }
154
155
156 public void start() throws CDMServerException {
157
158 /**
159 * First check if the CDM server responds to a service request, which implies that
160 * the server has started properly. If no response is received then check if the
161 * server is listening on specific host / port, which implies that the server
162 * has started but incorrectly, in which case we try to force stop it (if we can)
163 * and start a new server.
164 */
165 if(isStarted(1)) {
166 logger.info("[CDM-Server] Server already running @ " + host + ":" + httpPort );
167 serverAlreadyRunning = true;
168 return;
169 }
170
171 Thread t = new Thread() {
172 @Override
173 public void run() {
174
175 StringBuffer output = new StringBuffer();
176 try{
177 Process p;
178 String command = "java "
179 + getVMArgs()
180 + " -jar "
181 + DEFAULT_JETTY_RUNNER_RESOURCE.getFile().getAbsolutePath()
182 + getStartServerArgs()
183 + getStopServerSettings()
184 + " "
185 + DEFAULT_CDM_WEBAPP_RESOURCE.getFile().getAbsolutePath();
186 logger.info("[CDM-Server] Starting server with Command : " + command);
187 p = Runtime.getRuntime().exec(command);
188
189 BufferedReader inpReader =
190 new BufferedReader(new InputStreamReader(p.getInputStream()));
191
192 BufferedReader errReader =
193 new BufferedReader(new InputStreamReader(p.getErrorStream()));
194
195 String line = "";
196 while ((line = inpReader.readLine())!= null) {
197 logger.info("[CDM-Server Start] : " + line);
198 }
199
200 while ((line = errReader.readLine())!= null) {
201 logger.info("[CDM-Server Start] : " + line);
202 }
203
204 } catch (Exception e) {
205 e.printStackTrace();
206 cdmse = new CDMServerException(e);
207 }
208 }
209 };
210
211 t.setDaemon(true);
212 cdmse = null;
213 t.start();
214
215 if(isStarted(50)) {
216 logger.info("[CDM-Server] Server running @ " + host + ":" + httpPort );
217 } else {
218 logger.info("[CDM-Server] Server not started within given interval");
219 // making sure to kill server if it is not started correctly
220 try {
221 stop(true);
222 } catch (Exception e) {
223 throw new CDMServerException("CDM Server could not be stopped : " + e.getMessage());
224 }
225 throw new CDMServerException("CDM Server not started : ");
226 }
227
228 }
229
230
231 public boolean isStarted(int checkingIntervals) throws CDMServerException {
232 CdmRemoteSourceBase crsb = new CdmRemoteSourceBase("local-cdm-server",
233 host,
234 httpPort,
235 contextPath,
236 null);
237 int intervalsCount = 0;
238 do {
239 try {
240 if(cdmse != null) {
241 return false;
242 }
243 boolean check = crsb.checkConnection();
244 if(check) {
245 logger.info("[CDM-Server] Running @ " + host + ":" + httpPort );
246 return true;
247 }
248 } catch (Exception e) {
249
250 }
251 try {
252 Thread.sleep(1000);
253 } catch (InterruptedException ie) {
254 throw new CDMServerException("Error checking CDM Server status", ie);
255 }
256 intervalsCount++;
257 } while (intervalsCount < checkingIntervals);
258 return false;
259 }
260
261 public void stop() throws Exception {
262 stop(false);
263 }
264
265 public void stop(boolean force) throws Exception {
266
267 if(!force) {
268 if(!getInstance().isStarted(1)) {
269 logger.info("[CDM-Server] Server already stopped @ " + host + ":" + httpPort );
270 return;
271 }
272 }
273
274 if(serverAlreadyRunning) {
275 return;
276 }
277 Thread t = new Thread() {
278 @Override
279 public void run() {
280 StringBuffer output = new StringBuffer();
281 try{
282 Process p;
283 String command = "java -jar " + DEFAULT_JETTY_RESOURCE.getFile().getAbsolutePath()
284 + getStopServerArgs() + " --stop ";
285 logger.info("[CDM-Server] Stop Command : " + command);
286 p = Runtime.getRuntime().exec(command);
287
288 BufferedReader inpReader =
289 new BufferedReader(new InputStreamReader(p.getInputStream()));
290
291 BufferedReader errReader =
292 new BufferedReader(new InputStreamReader(p.getErrorStream()));
293
294 String line = "";
295 while ((line = inpReader.readLine())!= null) {
296 logger.info("[CDM-Server Stop] : " + line);
297 }
298
299 while ((line = errReader.readLine())!= null) {
300 logger.info("[CDM-Server Stop] : " + line);
301 }
302 logger.info("CDM-Server Stopped : ");
303 } catch (Exception e) {
304 logger.info("[CDM-Server] Could not stop @ " + host + ":" + httpPort + ". Please kill it manually");
305
306 }
307
308 }
309 };
310
311 t.setDaemon(true);
312 t.start();
313
314 }
315
316 public static void stopServerViaJMX(int jmxPort) throws CDMServerException {
317 String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/jmxrmi";
318 logger.warn("Shutting down Jetty instance ... ");
319
320 try {
321 JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), null);
322 connector.connect(null);
323 MBeanServerConnection connection = connector.getMBeanServerConnection();
324 ObjectName objectName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
325 connection.invoke(objectName, "stop", null, null);
326 logger.warn("Shutdown command sent");
327 } catch (InstanceNotFoundException e) {
328 throw new CDMServerException(e);
329 } catch (MBeanException e) {
330 throw new CDMServerException(e);
331 } catch (ReflectionException e) {
332 throw new CDMServerException(e);
333 } catch (IOException e) {
334 throw new CDMServerException(e);
335 } catch (MalformedObjectNameException e) {
336 throw new CDMServerException(e);
337 }
338
339
340
341 }
342 }