Project

General

Profile

Download (11.6 KB) Statistics
| Branch: | Tag: | Revision:
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.taxeditor.exception.CDMServerException;
28
import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSourceBase;
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
                return true;
261
            }
262
            try {
263
                Thread.sleep(1000);
264
            } catch (InterruptedException ie) {
265
                throw new CDMServerException("Error checking CDM Server status", ie);
266
            }
267
            intervalsCount++;
268
        } while (intervalsCount < checkingIntervals);
269

    
270
        return false;
271
    }
272

    
273
    public boolean isRunning(int checkingIntervals) throws CDMServerException  {
274
        CdmRemoteSourceBase crsb = new CdmRemoteSourceBase("local-cdm-server",
275
                host,
276
                port,
277
                contextPath,
278
                null);
279
        int intervalsCount = 0;
280
        do {
281
            try {
282
                if(cdmse != null) {
283
                    return false;
284
                }
285
                if(crsb.checkConnection()) {
286
                    logger.info("[CDM-Server] Running @ " + host + ":" + port );
287
                    return true;
288
                }
289
            } catch (Exception e) {
290
            }
291
            try {
292
                Thread.sleep(1000);
293
            } catch (InterruptedException ie) {
294
                throw new CDMServerException("Error checking CDM Server status", ie);
295
            }
296
            intervalsCount++;
297
        } while (intervalsCount < checkingIntervals);
298
        return false;
299
    }
300

    
301
    public void stop() throws Exception {
302
        stop(false);
303
    }
304
    public void stop(boolean force) throws Exception {
305

    
306
        if(!force) {
307
            if(!getInstance().isAvailable(1)) {
308
                logger.info("[CDM-Server] Server already stopped @ " + host + ":" + port );
309
                return;
310
            }
311

    
312
            if(getInstance().getKeepServerRunning()) {
313
                logger.info("[CDM-Server] Server @ " + host + ":" + port + " is set to keep running");
314
                return;
315
            }
316
        }
317
        Thread t = new Thread() {
318
            @Override
319
            public void run() {
320
                StringBuffer output = new StringBuffer();
321
                try{
322
                    Process p;
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);
327
                    p.waitFor();
328
                    BufferedReader reader =
329
                            new BufferedReader(new InputStreamReader(p.getInputStream()));
330
                    String line = "";
331
                    while ((line = reader.readLine())!= null) {
332
                        logger.info("CDM-Server Stop : " + line + "\n");
333
                    }
334
                } catch (Exception e) {
335
                    e.printStackTrace();
336
                }
337

    
338
            }
339
        };
340

    
341
        t.setDaemon(true);
342
        t.start();
343

    
344
        if(isStopped(5)) {
345
            logger.info("[CDM-Server] Stopped Server @ " + host + ":" + port );
346
        } else {
347
            logger.info("[CDM-Server] Could not stop @ " + host + ":" + port + ". Please kill it manually");
348
        }
349
    }
350
}
(2-2/7)