1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.jumpmind.symmetric;
21
22 import javax.management.Attribute;
23 import javax.management.MBeanServer;
24 import javax.management.MalformedObjectNameException;
25 import javax.management.ObjectName;
26
27 import mx4j.tools.adaptor.http.HttpAdaptor;
28 import mx4j.tools.adaptor.http.XSLTProcessor;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.jumpmind.symmetric.common.Constants;
33 import org.jumpmind.symmetric.common.ParameterConstants;
34 import org.jumpmind.symmetric.service.IParameterService;
35 import org.jumpmind.symmetric.util.AppUtils;
36 import org.jumpmind.symmetric.web.SymmetricFilter;
37 import org.jumpmind.symmetric.web.SymmetricServlet;
38 import org.mortbay.jetty.Connector;
39 import org.mortbay.jetty.Server;
40 import org.mortbay.jetty.nio.SelectChannelConnector;
41 import org.mortbay.jetty.servlet.Context;
42 import org.mortbay.jetty.servlet.ServletHolder;
43
44 /***
45 * Start up SymmetricDS through an embedded Jetty instance.
46 *
47 * @see SymmetricLauncher#main(String[])
48 */
49 public class SymmetricWebServer {
50
51 protected static final Log logger = LogFactory.getLog(SymmetricWebServer.class);
52
53 protected SymmetricEngineContextLoaderListener contextListener;
54
55 protected Server server;
56
57 protected boolean join = true;
58
59 protected String webHome = "/sync";
60
61 public SymmetricWebServer() {}
62
63 public SymmetricWebServer(SymmetricEngine engine) {
64 this.contextListener = new SymmetricEngineContextLoaderListener(engine);
65 }
66 public void start(int port, String propertiesUrl) throws Exception {
67 System.setProperty(Constants.OVERRIDE_PROPERTIES_FILE_1, propertiesUrl);
68 start(port);
69 }
70
71 public SymmetricEngine getEngine() {
72 if (contextListener != null) {
73 return contextListener.getEngine();
74 } else {
75 return null;
76 }
77 }
78
79 public void start(int port) throws Exception {
80 server = new Server();
81 Connector connector = new SelectChannelConnector();
82 connector.setPort(port);
83 server.setConnectors(new Connector[] { connector });
84
85 Context webContext = new Context(server, webHome, Context.NO_SESSIONS);
86
87 if (this.contextListener == null) {
88 this.contextListener = new SymmetricEngineContextLoaderListener();
89 }
90
91 webContext.addEventListener(this.contextListener);
92
93 webContext.addFilter(SymmetricFilter.class, "/*", 0);
94
95 ServletHolder servletHolder = new ServletHolder(SymmetricServlet.class);
96 servletHolder.setInitOrder(0);
97 webContext.addServlet(servletHolder, "/*");
98
99 server.addHandler(webContext);
100
101 logger.info("About to start SymmetricDS web server on port " + port);
102 server.start();
103
104 registerHttpJmxAdaptor(port + 1);
105
106 if (join) {
107 server.join();
108 }
109 }
110
111 protected void registerHttpJmxAdaptor(int jmxPort) throws Exception {
112 IParameterService parameterService = AppUtils.find(Constants.PARAMETER_SERVICE, getEngine());
113 if (parameterService.is(ParameterConstants.JMX_HTTP_CONSOLE_ENABLED)) {
114 logger.info("Starting JMX HTTP console on port " + jmxPort);
115 MBeanServer mbeanServer = AppUtils.find(Constants.MBEAN_SERVER, getEngine());
116 ObjectName name = getHttpJmxAdaptorName();
117 mbeanServer.createMBean(HttpAdaptor.class.getName(), name);
118 mbeanServer.setAttribute(name, new Attribute("Port", new Integer(jmxPort)));
119 ObjectName processorName = getXslJmxAdaptorName();
120 mbeanServer.createMBean(XSLTProcessor.class.getName(), processorName);
121 mbeanServer.setAttribute(name, new Attribute("ProcessorName", processorName));
122 mbeanServer.invoke(name, "start", null, null);
123 }
124 }
125
126 protected ObjectName getHttpJmxAdaptorName() throws MalformedObjectNameException {
127 return new ObjectName("Server:name=HttpAdaptor");
128 }
129
130 protected ObjectName getXslJmxAdaptorName() throws MalformedObjectNameException {
131 return new ObjectName("Server:name=XSLTProcessor");
132 }
133
134
135 protected void removeHttpJmxAdaptor() {
136 IParameterService parameterService = AppUtils.find(Constants.PARAMETER_SERVICE, getEngine());
137 if (parameterService.is(ParameterConstants.JMX_HTTP_CONSOLE_ENABLED)) {
138 try {
139 MBeanServer mbeanServer = AppUtils.find(Constants.MBEAN_SERVER, getEngine());
140 mbeanServer.unregisterMBean(getHttpJmxAdaptorName());
141 mbeanServer.unregisterMBean(getXslJmxAdaptorName());
142 } catch (Exception e) {
143 logger.warn("Could not unregister the JMX HTTP Adaptor");
144 }
145 }
146 }
147
148 public void stop() throws Exception {
149 if (server != null) {
150 removeHttpJmxAdaptor();
151 server.stop();
152 }
153 }
154
155 public SymmetricEngineContextLoaderListener getContextListener() {
156 return contextListener;
157 }
158
159 /***
160 * Before starting the web server, you have the option of overriding the
161 * default context listener.
162 *
163 * @param contextListener
164 * Usually an overridden instance
165 */
166 public void setContextListener(SymmetricEngineContextLoaderListener contextListener) {
167 this.contextListener = contextListener;
168 }
169
170 public static void main(String[] args) throws Exception {
171 new SymmetricWebServer().start(8080);
172 }
173
174 public boolean isJoin() {
175 return join;
176 }
177
178 public void setJoin(boolean join) {
179 this.join = join;
180 }
181
182 public void setWebHome(String webHome) {
183 this.webHome = webHome;
184 }
185
186 }