View Javadoc

1   /*
2    * SymmetricDS is an open source database synchronization solution.
3    *   
4    * Copyright (C) Chris Henson <chenson42@users.sourceforge.net>
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see
18   * <http://www.gnu.org/licenses/>.
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 }