Rest API for Historian data
[simantics/platform.git] / bundles / org.simantics.history.rest / src / org / simantics / history / rest / HistoryRestServer.java
1 package org.simantics.history.rest;
2
3 import java.util.EnumSet;
4 import java.util.concurrent.Semaphore;
5
6 import javax.servlet.DispatcherType;
7
8 import org.eclipse.jetty.server.Connector;
9 import org.eclipse.jetty.server.Server;
10 import org.eclipse.jetty.server.ServerConnector;
11 import org.eclipse.jetty.servlet.FilterHolder;
12 import org.eclipse.jetty.servlet.ServletContextHandler;
13 import org.eclipse.jetty.servlet.ServletHolder;
14 import org.glassfish.jersey.jackson.JacksonFeature;
15 import org.glassfish.jersey.server.ResourceConfig;
16 import org.glassfish.jersey.servlet.ServletContainer;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 public class HistoryRestServer {
21 private static final Logger LOGGER = LoggerFactory.getLogger(HistoryRestServer.class);
22     
23     private static HistoryRestServer INSTANCE = null;
24     private static Server server;
25     private static ServiceServerThread serverThread;
26     
27     private static String allowOriginUrl = null; 
28     
29     private static String address = null;
30     
31     private HistoryRestServer(int port) {
32          ResourceConfig config = new ResourceConfig();
33          // JSON serialization/deserialization
34          config.register(JacksonFeature.class);
35          // Actual API
36          config.register(HistoryRestApi.class);
37          
38          ServletHolder holder = new ServletHolder(new ServletContainer(config));
39          
40          server = new Server();
41          ServerConnector connector = new ServerConnector(server);
42          connector.setPort(port);
43          
44          server.setConnectors(new Connector[] { connector });
45          
46          ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
47          context.addServlet(holder, "/*");
48          
49          if (allowOriginUrl != null){
50                 org.eclipse.jetty.servlets.CrossOriginFilter cfilter = new org.eclipse.jetty.servlets.CrossOriginFilter();
51                 FilterHolder filterHolder = new FilterHolder(cfilter);
52                 filterHolder.setInitParameter(org.eclipse.jetty.servlets.CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, allowOriginUrl);
53                 context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
54          }
55     }
56     
57     
58     private static class ServiceServerThread extends Thread {
59
60         Semaphore s;
61         @Override
62         public void run() {
63             try {
64                 server.start();
65                 address = server.getURI().toString()+"history/";
66                 if (s != null)
67                         s.release();
68                 server.join();
69             } catch (Exception e) {
70                 LOGGER.error("Could not start server ", e);
71             }
72         }
73         
74         public void startAndWait() {
75                 s = new Semaphore(0);
76                 this.start();
77                 try {
78                         s.acquire();
79                 } catch (InterruptedException e) {};
80         }
81     }
82     
83     private static synchronized HistoryRestServer getInstance(int port) {
84         try {
85             if (INSTANCE == null) {
86                 INSTANCE = new HistoryRestServer(port);
87             }
88         } catch (Exception e) {
89             LOGGER.error("Could not initialize SCL REST server", e);
90         }
91         return INSTANCE;
92     }
93     
94     public static HistoryRestServer getRunningInstance() {
95         return INSTANCE;
96     }
97     
98     public static void setAllowOrigin(String url) {
99         allowOriginUrl = url;
100     }
101
102     public static synchronized void startAsync(int port) throws Exception {
103         // Ensure that an instance is created
104         getInstance(port);
105         if (serverThread == null && server != null) {
106             serverThread = new ServiceServerThread();
107             serverThread.start();
108         }
109     }
110     
111     public static synchronized void start(int port) throws Exception {
112         // Ensure that an instance is created
113         getInstance(port);
114         if (serverThread == null && server != null) {
115             serverThread = new ServiceServerThread();
116             serverThread.startAndWait();
117         }
118     }
119     
120     public static synchronized void stop() throws Exception {
121         if (server != null)
122             server.stop();
123         serverThread = null;
124         INSTANCE = null;
125         address = null;
126         
127     }
128     
129     public static synchronized boolean running() {
130         return INSTANCE != null;
131     }
132     
133     public static synchronized String address() {
134         return address;
135     }
136
137 }