-// $Id$
-/**
- * Copyright (C) 2014 EDIT
- * European Distributed Institute of Taxonomy
- * http://www.e-taxonomy.eu
- *
- * The contents of this file are subject to the Mozilla Public License Version 1.1
- * See LICENSE.TXT at the top of this package for the full license terms.
- */
-package eu.etaxonomy.taxeditor.httpinvoker;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.Properties;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.sql.DataSource;
-
-import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.FileLocator;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
-import org.unitils.database.annotations.TestDataSource;
-
-import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
-import eu.etaxonomy.cdm.database.ICdmDataSource;
-import eu.etaxonomy.taxeditor.remoting.server.CDMServerException;
-import eu.etaxonomy.taxeditor.remoting.source.CdmRemoteSourceBase;
-
-/**
- *
- * (Singleton) Server instance which manages a compatible cdmlib-webapp-war.
- * This is done by launching a jetty instance (using jetty-runner) as an
- * executed process. The choice of the external process over a more
- * preferable 'embedded jetty' instance is due to problems arising from the
- * class loading of classes (e.g. from hibernate core) which are needed
- * for both the webapp as well as the remoting client.
- *
- * @author cmathew
- * @date 23 Sep 2014
- *
- */
-
-public class CDMServer {
-
- public static final Logger logger = Logger.getLogger(CDMServer.class);
-
- @TestDataSource
- protected DataSource dataSource;
-
- private final String name = "default";
- private final String host = "127.0.0.1";
- private int httpPort = 9090;
- private int stopPort = 9191;
- private String stopKey = "jetty-cdm-server";
- private final String contextPath = "";
-
- public static final Resource DEFAULT_CDM_WEBAPP_RESOURCE =
- new ClassPathResource("/etc/jetty/cdmlib-remote-webapp.war");
-
- public static final Resource DEFAULT_DATASOURCE_FILE =
- new ClassPathResource("datasources.xml");
-
- public static final Resource DEFAULT_JETTY_RUNNER_RESOURCE =
- new ClassPathResource("/etc/jetty/jetty-runner-9.2.3.v20140905.jar");
-
- public static final Resource DEFAULT_JETTY_RESOURCE =
- new ClassPathResource("/etc/jetty/start-9.2.3.v20140905.jar");
-
- private static CDMServer cdmServer = null;
- private static CDMServerException cdmse = null;
-
- private boolean serverAlreadyRunning = false;
-
- private File dataSourcesFile;
- private final String dataSourceName;
-
- public CDMServer(String dataSourceName, URL serverPropertiesURL) throws CDMServerException {
- this.dataSourceName = dataSourceName;
- Properties prop = new Properties();
-
- try {
- File serverPropertiesFile = new File(FileLocator.resolve(serverPropertiesURL).toURI());
- InputStream inputStream = new FileInputStream(serverPropertiesFile);
-
- prop.load(inputStream);
- inputStream.close();
-
- } catch (FileNotFoundException e) {
- throw new CDMServerException(e);
- } catch (URISyntaxException e) {
- throw new CDMServerException(e);
- } catch (IOException e) {
- throw new CDMServerException(e);
- }
-
-
-
- if(prop.getProperty("httpPort") != null) {
- setHttpPort(Integer.valueOf(prop.getProperty("httpPort")));
- }
-
- if(prop.getProperty("stopPort") != null) {
- setStopPort(Integer.valueOf(prop.getProperty("stopPort")));
- }
-
- if(prop.getProperty("stopKey") != null) {
- setStopKey(prop.getProperty("stopKey"));
- }
-
- }
-
-
-
- public String getName() {
- return name;
- }
-
- public String getHost() {
- return host;
- }
-
- public int getPort() {
- return httpPort;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- public void setHttpPort(int port) {
- this.httpPort = port;
- }
-
- public void setStopPort(int stopPort) {
- this.stopPort = stopPort;
- }
-
- public void setStopKey(String stopKey) {
- this.stopKey = stopKey;
- }
-
-
- public static boolean isRunningInEclipse() {
- return (System.getProperty("sun.java.command") != null &&
- System.getProperty("sun.java.command").startsWith("org.eclipse.jdt.internal.junit.runner.RemoteTestRunner"));
- }
-
- private String getVMArgs() throws IOException {
- StringBuilder sb = new StringBuilder();
- sb.append(" -Dspring.profiles.active=remoting");
- sb.append(" -Dcdm.beanDefinitionFile=" + DEFAULT_DATASOURCE_FILE.getFile().getAbsolutePath());
- sb.append(" -Dcdm.datasource=cdmTest");
- return sb.toString();
- }
-
- private String getStartServerArgs() throws IOException {
- StringBuilder sb = new StringBuilder();
- sb.append(" --port " + httpPort);
- return sb.toString();
- }
-
- private String getStopServerSettings() {
- StringBuilder sb = new StringBuilder();
- sb.append(" --stop-port ");
- sb.append(stopPort);
- sb.append(" --stop-key ");
- sb.append(stopKey);
- return sb.toString();
- }
-
- private String getStopServerArgs() {
- StringBuilder sb = new StringBuilder();
- sb.append(" STOP.PORT=");
- sb.append(stopPort);
- sb.append(" STOP.KEY=");
- sb.append(stopKey);
- return sb.toString();
- }
-
-
- public void start() throws CDMServerException {
-
- /**
- * First check if the CDM server responds to a service request, which implies that
- * the server has started properly. If no response is received then check if the
- * server is listening on specific host / port, which implies that the server
- * has started but incorrectly, in which case we try to force stop it (if we can)
- * and start a new server.
- */
- if(isStarted(1)) {
- logger.info("[CDM-Server] Server already running @ " + host + ":" + httpPort );
- serverAlreadyRunning = true;
- return;
- }
-
- Thread t = new Thread() {
- @Override
- public void run() {
-
- StringBuffer output = new StringBuffer();
- try{
- Process p;
- String command = "java "
- + getVMArgs()
- + " -jar "
- + DEFAULT_JETTY_RUNNER_RESOURCE.getFile().getAbsolutePath()
- + getStartServerArgs()
- + getStopServerSettings()
- + " "
- + DEFAULT_CDM_WEBAPP_RESOURCE.getFile().getAbsolutePath();
- logger.info("[CDM-Server] Starting server with Command : " + command);
- p = Runtime.getRuntime().exec(command);
-
- BufferedReader inpReader =
- new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedReader errReader =
- new BufferedReader(new InputStreamReader(p.getErrorStream()));
-
- String line = "";
- while ((line = inpReader.readLine())!= null) {
- logger.info("[CDM-Server Start] : " + line);
- }
-
- while ((line = errReader.readLine())!= null) {
- logger.info("[CDM-Server Start] : " + line);
- }
-
- } catch (Exception e) {
- e.printStackTrace();
- cdmse = new CDMServerException(e);
- }
- }
- };
-
- t.setDaemon(true);
- cdmse = null;
- t.start();
-
- if(isStarted(50)) {
- logger.info("[CDM-Server] Server running @ " + host + ":" + httpPort );
- } else {
- logger.info("[CDM-Server] Server not started within given interval");
- // making sure to kill server if it is not started correctly
- try {
- stop(true);
- } catch (Exception e) {
- throw new CDMServerException("CDM Server could not be stopped : " + e.getMessage());
- }
- throw new CDMServerException("CDM Server not started : ");
- }
-
- }
-
-
- public boolean isStarted(int checkingIntervals) throws CDMServerException {
- CdmRemoteSourceBase crsb = new CdmRemoteSourceBase("local-cdm-server",
- host,
- httpPort,
- contextPath,
- null);
- int intervalsCount = 0;
- do {
- try {
- if(cdmse != null) {
- return false;
- }
- boolean check = crsb.checkConnection();
- if(check) {
- logger.info("[CDM-Server] Running @ " + host + ":" + httpPort );
- return true;
- }
- } catch (Exception e) {
-
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException ie) {
- throw new CDMServerException("Error checking CDM Server status", ie);
- }
- intervalsCount++;
- } while (intervalsCount < checkingIntervals);
- return false;
- }
-
- public void stop() throws Exception {
- stop(false);
- }
-
- public void stop(boolean force) throws Exception {
-
- if(!force) {
- if(!cdmServer.isStarted(1)) {
- logger.info("[CDM-Server] Server already stopped @ " + host + ":" + httpPort );
- return;
- }
- }
-
- if(serverAlreadyRunning) {
- return;
- }
- Thread t = new Thread() {
- @Override
- public void run() {
- StringBuffer output = new StringBuffer();
- try{
- Process p;
- String command = "java -jar " + DEFAULT_JETTY_RESOURCE.getFile().getAbsolutePath()
- + getStopServerArgs() + " --stop ";
- logger.info("[CDM-Server] Stop Command : " + command);
- p = Runtime.getRuntime().exec(command);
-
- BufferedReader inpReader =
- new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedReader errReader =
- new BufferedReader(new InputStreamReader(p.getErrorStream()));
-
- String line = "";
- while ((line = inpReader.readLine())!= null) {
- logger.info("[CDM-Server Stop] : " + line);
- }
-
- while ((line = errReader.readLine())!= null) {
- logger.info("[CDM-Server Stop] : " + line);
- }
- logger.info("CDM-Server Stopped : ");
- } catch (Exception e) {
- logger.info("[CDM-Server] Could not stop @ " + host + ":" + httpPort + ". Please kill it manually");
-
- }
-
- }
- };
-
- t.setDaemon(true);
- t.start();
-
- }
-
- public static void stopServerViaJMX(int jmxPort) throws CDMServerException {
- String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:" + jmxPort + "/jmxrmi";
- logger.warn("Shutting down Jetty instance ... ");
-
- try {
- JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(JMX_URL), null);
- connector.connect(null);
- MBeanServerConnection connection = connector.getMBeanServerConnection();
- ObjectName objectName = new ObjectName("org.eclipse.jetty.server:type=server,id=0");
- connection.invoke(objectName, "stop", null, null);
- logger.warn("Shutdown command sent");
- } catch (InstanceNotFoundException e) {
- throw new CDMServerException(e);
- } catch (MBeanException e) {
- throw new CDMServerException(e);
- } catch (ReflectionException e) {
- throw new CDMServerException(e);
- } catch (IOException e) {
- throw new CDMServerException(e);
- } catch (MalformedObjectNameException e) {
- throw new CDMServerException(e);
- }
- }
-
- public void convertEditorToServerConfig() {
- String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + System.lineSeparator() +
- "<beans xmlns=\"http://www.springframework.org/schema/beans\"" + System.lineSeparator() +
- "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + System.lineSeparator() +
- "xmlns:tx=\"http://www.springframework.org/schema/tx\"" + System.lineSeparator() +
- "xmlns:context=\"http://www.springframework.org/schema/context\"" + System.lineSeparator() +
- "xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd" + System.lineSeparator() +
- "http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" + System.lineSeparator() +
- "http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd" + System.lineSeparator() +
- ">" + System.lineSeparator() +
- "<bean id=\"dataSourceProperties\" class=\"eu.etaxonomy.cdm.remote.config.DataSourceProperties\">" + System.lineSeparator() +
- " <property name=\"propsMap\">" + System.lineSeparator() +
- " <map/>" + System.lineSeparator() +
- " </property>" + System.lineSeparator() +
- "</bean>";
-
- for(ICdmDataSource dataSource : CdmPersistentDataSource.getAllDataSources()) {
-
- }
- }
-}