+++ /dev/null
-/**
- * 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.local;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-
-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 org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.util.preventers.AppContextLeakPreventer;
-import org.eclipse.jetty.webapp.WebAppContext;
-import org.osgi.framework.Bundle;
-
-import eu.etaxonomy.taxeditor.workbench.datasource.ICdmServerError;
-
-/**
- * (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);
-
- //TODO use the constants defined in eu.etaxonomy.cdm.opt.config.DataSourceConfigurer
- private static final String ATTRIBUTE_FORCE_SCHEMA_CREATE = "cdm.forceSchemaCreate";
- private static final String ATTRIBUTE_FORCE_SCHEMA_UPDATE = "cdm.forceSchemaUpdate";
- private static final String ATTRIBUTE_DATASOURCE_NAME = "cdm.datasource";
- private static final String CDM_BEAN_DEFINITION_FILE = "cdm.beanDefinitionFile";
-
- //see eu.etaxonomy.cdm.server.Bootloader.SPRING_PROFILES_ACTIVE
- private static final String SPRING_PROFILES_ACTIVE = "spring.profiles.active";
-
-
- private final String dataSourceName;
- private final String host = "127.0.0.1";
- private int httpPort = 9090;
- private final String contextPath = "/";
-
- private File warFile;
- private Server server;
-
- private boolean forceSchemaCreate = false;
- private boolean forceSchemaUpdate = false;
-
- public CdmServer(String dataSourceName, File dataSourcesFile) throws CdmEmbeddedServerException {
- if(StringUtils.isBlank(dataSourceName)) {
- throw new CdmEmbeddedServerException("DataSource name is not valid");
- }
-
- if(dataSourcesFile == null || !dataSourcesFile.exists()) {
- throw new CdmEmbeddedServerException("DataSource config file does not exist");
- }
- this.dataSourceName = dataSourceName;
- Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.webapp");
- URL warURL = bundle.getEntry("lib/cdmlib-remote-webapp.war");
-
- try {
- URL resolvedWarURL = FileLocator.toFileURL(warURL);
- // We need to use the 3-arg constructor of URI in order to properly escape file system chars
- URI resolvedURI = new URI(resolvedWarURL.getProtocol(), resolvedWarURL.getPath(), null);
- warFile = new File(resolvedURI);
- System.out.println("war url : " + warFile.getAbsolutePath());
-
- if(warFile == null || !warFile.exists()) {
- throw new CdmEmbeddedServerException("Cdmlib War file does not exist");
- }
- } catch (URISyntaxException use) {
- throw new CdmEmbeddedServerException(use);
- } catch (IOException ioe) {
- throw new CdmEmbeddedServerException(ioe);
- }
-
- System.setProperty(SPRING_PROFILES_ACTIVE, "remoting");
- System.setProperty(CDM_BEAN_DEFINITION_FILE, dataSourcesFile.getAbsolutePath());
- System.setProperty(ATTRIBUTE_DATASOURCE_NAME, dataSourceName);
-
- httpPort = findFreePort();
-
- logger.warn("Starting server on port : " + httpPort);
-
- server = new Server(httpPort);
-
- server.addBean(new AppContextLeakPreventer());
-
- WebAppContext webapp = new WebAppContext();
-
- webapp.setContextPath(contextPath);
- webapp.setWar(warFile.getAbsolutePath());
- webapp.setThrowUnavailableOnStartupException(true);
-
- server.setHandler(webapp);
- }
-
- public String getDataSourceName() {
- return dataSourceName;
- }
- public String getHost() {
- return host;
- }
-
- public int getPort() {
- return httpPort;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- private static int findFreePort() throws CdmEmbeddedServerException {
- ServerSocket socket = null;
- try {
- socket = new ServerSocket(0);
- socket.setReuseAddress(true);
- int port = socket.getLocalPort();
- try {
- socket.close();
- } catch (IOException e) {
-
- }
- return port;
- } catch (IOException e) {
- } finally {
- if (socket != null) {
- try {
- socket.close();
- } catch (IOException e) {
- }
- }
- }
- throw new CdmEmbeddedServerException("Could not find a free TCP/IP port to start embedded Jetty HTTP Server on");
- }
-
- public void start(ICdmServerError cdmServerError) throws CdmEmbeddedServerException {
- start(true, cdmServerError);
- }
-
- public void start(boolean wait, final ICdmServerError remotingLoginDialogLocal) throws CdmEmbeddedServerException {
-
- if(server == null) {
- throw new CdmEmbeddedServerException("Server is already disposed");
- }
-
- if(server.isStarting()) {
- throw new CdmEmbeddedServerException("Server is starting");
- }
-
- if(server.isStarted()) {
- throw new CdmEmbeddedServerException("Server has started");
- }
-
- if(server.isRunning()) {
- throw new CdmEmbeddedServerException("Server is running");
- }
-
- if(server.isStopping()) {
- throw new CdmEmbeddedServerException("Server is currently stopping. Please re-try in about 10 seconds");
- }
-
- Thread serverThread = new Thread() {
-
- @Override
- public void run() {
- try {
- if(isForceSchemaCreate()) {
- System.setProperty(ATTRIBUTE_FORCE_SCHEMA_CREATE, "true");
- }else if (isForceSchemaUpdate()){
- System.setProperty(ATTRIBUTE_FORCE_SCHEMA_UPDATE, "true");
- }
- server.start();
- server.join();
- } catch (Throwable t) {
- //wait for 1sec to get the right order of login dialog and error
- //message when connection fails
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- Throwable cause = t;
- while(cause != null) {
-
- // pure string comparison to avoid dependencies to hibernate or cdmlib-persistance in the taxeditor
- if(cause.getClass().getSimpleName().equals("SchemaExtractionException") || cause.getClass().getSimpleName().equals("CdmDatabaseException") ) {
- logger.debug(cause.getClass().getName() + " detected which indicates missing or corrupt schema");
- cause = null;
- } else {
- cause = cause.getCause();
- }
- }
- remotingLoginDialogLocal.handleError(new RuntimeException("Error during CDM server startup", t));
- }
- }
- };
-
- serverThread.start();
-
- if(wait) {
- while(!server.isStarted()) {}
- }
- }
-
- public boolean isAlive() {
- return server.isRunning() || server.isStarting() || server.isStarted();
- }
-
- public boolean isStarted() {
- return server.isStarted();
- }
-
- public boolean isFailed() {
- return server.isFailed();
- }
-
- public void stop() throws Exception {
- server.stop();
- server.destroy();
- server = null;
- }
-
- public static void stopServerViaJMX(int jmxPort) throws CdmEmbeddedServerException {
- 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 CdmEmbeddedServerException(e);
- } catch (MBeanException e) {
- throw new CdmEmbeddedServerException(e);
- } catch (ReflectionException e) {
- throw new CdmEmbeddedServerException(e);
- } catch (IOException e) {
- throw new CdmEmbeddedServerException(e);
- } catch (MalformedObjectNameException e) {
- throw new CdmEmbeddedServerException(e);
- }
- }
-
- public boolean isForceSchemaCreate() {
- return forceSchemaCreate;
- }
-
- public void setForceSchemaCreate(boolean forceSchemaCreate) {
- this.forceSchemaCreate = forceSchemaCreate;
- }
-
- public boolean isForceSchemaUpdate() {
- return forceSchemaUpdate;
- }
- public void setForceSchemaUpdate(boolean forceSchemaUpdate) {
- this.forceSchemaUpdate = forceSchemaUpdate;
- }
-}