package org.simantics.history.rest; import java.util.EnumSet; import java.util.concurrent.Semaphore; import javax.servlet.DispatcherType; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.servlet.ServletContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HistoryRestServer { private static final Logger LOGGER = LoggerFactory.getLogger(HistoryRestServer.class); private static HistoryRestServer INSTANCE = null; private static Server server; private static ServiceServerThread serverThread; private static String allowOriginUrl = null; private static String address = null; private HistoryRestServer(int port) { ResourceConfig config = new ResourceConfig(); // JSON serialization/deserialization config.register(JacksonFeature.class); // Actual API config.register(HistoryRestApi.class); ServletHolder holder = new ServletHolder(new ServletContainer(config)); server = new Server(); ServerConnector connector = new ServerConnector(server); connector.setPort(port); server.setConnectors(new Connector[] { connector }); ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS); context.addServlet(holder, "/*"); if (allowOriginUrl != null){ org.eclipse.jetty.servlets.CrossOriginFilter cfilter = new org.eclipse.jetty.servlets.CrossOriginFilter(); FilterHolder filterHolder = new FilterHolder(cfilter); filterHolder.setInitParameter(org.eclipse.jetty.servlets.CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, allowOriginUrl); context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class)); } } private static class ServiceServerThread extends Thread { Semaphore s; @Override public void run() { try { server.start(); address = server.getURI().toString()+"history/"; if (s != null) s.release(); server.join(); } catch (Exception e) { LOGGER.error("Could not start server ", e); } } public void startAndWait() { s = new Semaphore(0); this.start(); try { s.acquire(); } catch (InterruptedException e) {}; } } private static synchronized HistoryRestServer getInstance(int port) { try { if (INSTANCE == null) { INSTANCE = new HistoryRestServer(port); } } catch (Exception e) { LOGGER.error("Could not initialize SCL REST server", e); } return INSTANCE; } public static HistoryRestServer getRunningInstance() { return INSTANCE; } public static void setAllowOrigin(String url) { allowOriginUrl = url; } public static synchronized void startAsync(int port) throws Exception { // Ensure that an instance is created getInstance(port); if (serverThread == null && server != null) { serverThread = new ServiceServerThread(); serverThread.start(); } } public static synchronized void start(int port) throws Exception { // Ensure that an instance is created getInstance(port); if (serverThread == null && server != null) { serverThread = new ServiceServerThread(); serverThread.startAndWait(); } } public static synchronized void stop() throws Exception { if (server != null) server.stop(); serverThread = null; INSTANCE = null; address = null; } public static synchronized boolean running() { return INSTANCE != null; } public static synchronized String address() { return address; } }