1 5 package com.tc.server; 6 7 import org.apache.commons.lang.StringUtils; 8 import org.mortbay.jetty.Server; 9 import org.mortbay.jetty.servlet.ServletHandler; 10 import org.mortbay.jetty.servlet.ServletHolder; 11 import org.mortbay.jetty.webapp.WebAppContext; 12 13 import EDU.oswego.cs.dl.util.concurrent.SynchronizedByte; 14 15 import com.tc.async.api.ConfigurationContext; 16 import com.tc.async.api.SEDA; 17 import com.tc.async.api.Sink; 18 import com.tc.async.api.Stage; 19 import com.tc.async.api.StageManager; 20 import com.tc.capabilities.AbstractCapabilitiesFactory; 21 import com.tc.config.schema.L2Info; 22 import com.tc.config.schema.NewCommonL2Config; 23 import com.tc.config.schema.NewSystemConfig; 24 import com.tc.config.schema.messaging.http.ConfigServlet; 25 import com.tc.config.schema.setup.ConfigurationSetupException; 26 import com.tc.config.schema.setup.L2TVSConfigurationSetupManager; 27 import com.tc.lang.StartupHelper; 28 import com.tc.lang.TCThreadGroup; 29 import com.tc.lang.ThrowableHandler; 30 import com.tc.lang.StartupHelper.StartupAction; 31 import com.tc.logging.CustomerLogging; 32 import com.tc.logging.TCLogger; 33 import com.tc.logging.TCLogging; 34 import com.tc.management.beans.L2MBeanNames; 35 import com.tc.management.beans.TCServerInfo; 36 import com.tc.net.protocol.tcm.CommunicationsManagerImpl; 37 import com.tc.net.protocol.transport.ConnectionPolicy; 38 import com.tc.net.protocol.transport.ConnectionPolicyImpl; 39 import com.tc.objectserver.core.impl.ServerManagementContext; 40 import com.tc.objectserver.impl.DistributedObjectServer; 41 import com.tc.stats.DSO; 42 import com.tc.stats.DSOMBean; 43 import com.tc.util.Assert; 44 45 import java.util.Date ; 46 47 import javax.management.InstanceAlreadyExistsException ; 48 import javax.management.MBeanRegistrationException ; 49 import javax.management.MBeanServer ; 50 import javax.management.NotCompliantMBeanException ; 51 52 public class TCServerImpl extends SEDA implements TCServer { 53 54 private static final TCLogger logger = TCLogging.getLogger(TCServer.class); 55 private static final TCLogger consoleLogger = CustomerLogging.getConsoleLogger(); 56 private static final byte STATE_STOPPED = 0; 57 private static final byte STATE_STARTED = 1; 58 private static final byte STATE_ACTIVE = 2; 59 60 private long startTime; 61 private long activateTime; 62 63 private CommunicationsManagerImpl commsManager; 64 private DistributedObjectServer dsoServer; 65 private Server httpServer; 66 private TerracottaConnector terracottaConnector; 67 68 private final Object stateLock = new Object (); 69 private final SynchronizedByte state = new SynchronizedByte(STATE_STOPPED); 70 71 private final L2TVSConfigurationSetupManager configurationSetupManager; 72 private final ConnectionPolicy connectionPolicy; 73 74 77 public TCServerImpl(L2TVSConfigurationSetupManager configurationSetupManager) { 78 this(configurationSetupManager, new TCThreadGroup(new ThrowableHandler(TCLogging.getLogger(TCServer.class)))); 79 } 80 81 public TCServerImpl(L2TVSConfigurationSetupManager configurationSetupManager, TCThreadGroup threadGroup) { 82 this(configurationSetupManager, threadGroup, new ConnectionPolicyImpl(Integer.MAX_VALUE)); 83 } 84 85 public TCServerImpl(L2TVSConfigurationSetupManager manager, TCThreadGroup group, ConnectionPolicy connectionPolicy) { 86 super(group); 87 this.connectionPolicy = connectionPolicy; 88 Assert.assertNotNull(manager); 89 this.configurationSetupManager = manager; 90 } 91 92 public L2Info[] infoForAllL2s() { 93 String [] allKnownL2s = this.configurationSetupManager.allCurrentlyKnownServers(); 94 L2Info[] out = new L2Info[allKnownL2s.length]; 95 96 for (int i = 0; i < out.length; ++i) { 97 try { 98 NewCommonL2Config config = this.configurationSetupManager.commonL2ConfigFor(allKnownL2s[i]); 99 100 String name = allKnownL2s[i]; 101 if (name == null) name = L2Info.IMPLICIT_L2_NAME; 102 103 String host = config.host().getString(); 104 if (StringUtils.isBlank(host)) host = name; 105 106 out[i] = new L2Info(name, host, config.jmxPort().getInt()); 107 } catch (ConfigurationSetupException cse) { 108 throw Assert.failure("This should be impossible here", cse); 109 } 110 } 111 112 return out; 113 } 114 115 public String getDescriptionOfCapabilities() { 116 return AbstractCapabilitiesFactory.getCapabilitiesManager().describe(); 117 } 118 119 123 public void stop() { 124 synchronized (stateLock) { 125 if (state.commit(STATE_ACTIVE, STATE_STOPPED)) { 126 stopServer(); 127 logger.info("Server stopped."); 128 } else { 129 logger.warn("Server in incorrect state (" + state.get() + ") to be stopped."); 130 } 131 } 132 133 } 134 135 public void start() { 136 synchronized (stateLock) { 137 if (state.commit(STATE_STOPPED, STATE_STARTED)) { 138 try { 139 startServer(); 140 if (!state.commit(STATE_STARTED, STATE_ACTIVE)) { 141 throw new AssertionError ("Server in incorrect state (" + state.get() + ") to be active."); 143 } 144 } catch (Throwable t) { 145 if(t instanceof RuntimeException ) { 146 throw (RuntimeException )t; 147 } 148 throw new RuntimeException (t); 149 } 150 } else { 151 logger.warn("Server in incorrect state (" + state.get() + ") to be started."); 152 } 153 } 154 } 155 156 public void shutdown() { 157 synchronized (stateLock) { 158 if (!isStopped()) { 159 stop(); 160 } 161 consoleLogger.info("Server exiting..."); 162 System.exit(0); 163 } 164 } 165 166 public long getStartTime() { 167 return startTime; 168 } 169 170 public long getActivateTime() { 171 synchronized (stateLock) { 172 return activateTime; 173 } 174 } 175 176 public int getDSOListenPort() { 177 if (dsoServer != null) { return dsoServer.getListenPort(); } 178 throw new IllegalStateException ("DSO Server not running"); 179 } 180 181 public void dump() { 182 if (dsoServer != null) { 183 dsoServer.dump(); 184 } 185 } 186 187 public DistributedObjectServer getDSOServer() { 188 return dsoServer; 189 } 190 191 public boolean isStarted() { 192 return state.compareTo(STATE_STARTED) == 0; 193 } 194 195 public boolean isActive() { 196 return state.compareTo(STATE_ACTIVE) == 0; 197 } 198 199 public boolean isStopped() { 200 return state.compareTo(STATE_STOPPED) == 0; 201 } 202 203 public String toString() { 204 StringBuffer buf = new StringBuffer (); 205 buf.append("Server: ").append(super.toString()).append("\n"); 206 if (isActive()) { 207 buf.append("Active since ").append(new Date (getStartTime())).append("\n"); 208 } else if (isStarted()) { 209 buf.append("Started at ").append(new Date (getStartTime())).append("\n"); 210 } else { 211 buf.append("Server is stopped").append("\n"); 212 } 213 214 return buf.toString(); 215 } 216 217 private void stopServer() { 218 220 if (logger.isDebugEnabled()) { 221 consoleLogger.debug("Stopping TC server..."); 222 } 223 224 if (commsManager != null) { 225 if (logger.isDebugEnabled()) { 226 logger.debug("Shutting down communications manager..."); 227 } 228 229 try { 230 commsManager.shutdown(); 231 } catch (Exception e) { 232 logger.error("Error shutting down comms manager", e); 233 } finally { 234 commsManager = null; 235 } 236 } 237 238 if (terracottaConnector != null) { 239 try { 240 terracottaConnector.shutdown(); 241 } catch (Exception e) { 242 logger.error("Error shutting down terracotta connector", e); 243 } finally { 244 terracottaConnector = null; 245 } 246 } 247 248 try { 249 getStageManager().stopAll(); 250 } catch (Exception e) { 251 logger.error("Error shutting down stage manager", e); 252 } 253 254 if (httpServer != null) { 255 if (logger.isDebugEnabled()) { 256 logger.debug("Shutting down HTTP server..."); 257 } 258 259 try { 260 httpServer.stop(); 261 } catch (Exception e) { 262 logger.error("Error shutting down HTTP server", e); 263 } finally { 264 httpServer = null; 265 } 266 } 267 268 if (dsoServer != null) { 270 try { 271 dsoServer.quickStop(); 272 } catch (Exception e) { 273 logger.error("Error shutting down DSO server", e); 274 } finally { 275 dsoServer = null; 276 } 277 } 278 279 } 280 281 private class StartAction implements StartupAction { 282 public void execute() throws Throwable { 283 if (logger.isDebugEnabled()) { 284 logger.debug("Starting Terracotta server..."); 285 } 286 287 startTime = System.currentTimeMillis(); 288 289 NewSystemConfig systemConfig = TCServerImpl.this.configurationSetupManager.systemConfig(); 290 terracottaConnector = new TerracottaConnector(); 291 startHTTPServer(systemConfig, terracottaConnector); 292 293 Stage stage = getStageManager().createStage("dso-http-bridge", new HttpConnectionHandler(terracottaConnector), 1, 294 100); 295 getStageManager().startAll(new NullContext(getStageManager())); 296 297 startDSOServer(stage.getSink()); 299 300 activateTime = System.currentTimeMillis(); 301 302 if (activationListener != null) { 303 activationListener.serverActivated(TCServerImpl.this); 304 } 305 } 306 } 307 308 protected void startServer() throws Exception { 309 new StartupHelper(getThreadGroup(), new StartAction()).startUp(); 310 } 311 312 private void startDSOServer(Sink httpSink) throws Exception { 313 dsoServer = new DistributedObjectServer(configurationSetupManager, getThreadGroup(), connectionPolicy, httpSink, 314 new TCServerInfo(this)); 315 dsoServer.start(); 316 317 registerDSOServer(); 318 } 319 320 private void startHTTPServer(NewSystemConfig systemConfig, TerracottaConnector tcConnector) throws Exception { 321 httpServer = new Server(); 322 httpServer.addConnector(tcConnector); 323 324 WebAppContext context = new WebAppContext("", "/"); 325 ServletHandler servletHandler = new ServletHandler(); 326 327 330 context.setResourceBase(System.getProperty("user.dir")); 331 332 ServletHolder holder; 333 holder = servletHandler.addServletWithMapping(VersionServlet.class.getName(), "/version"); 334 servletHandler.addServlet(holder); 335 336 context.setAttribute(ConfigServlet.CONFIG_ATTRIBUTE, this.configurationSetupManager); 337 holder = servletHandler.addServletWithMapping(ConfigServlet.class.getName(), "/config"); 338 servletHandler.addServlet(holder); 339 340 context.setServletHandler(servletHandler); 341 httpServer.addHandler(context); 342 343 try { 344 httpServer.start(); 345 } catch (Exception e) { 346 consoleLogger.warn("Couldn't start HTTP server", e); 347 throw e; 348 } 349 } 350 351 private void registerDSOServer() throws InstanceAlreadyExistsException , MBeanRegistrationException , 352 NotCompliantMBeanException , NullPointerException { 353 354 ServerManagementContext mgmtContext = dsoServer.getManagementContext(); 355 MBeanServer mBeanServer = dsoServer.getMBeanServer(); 356 DSOMBean dso = new DSO(mgmtContext, mBeanServer); 357 mBeanServer.registerMBean(dso, L2MBeanNames.DSO); 358 mBeanServer.registerMBean(mgmtContext.getDSOAppEventsMBean(), L2MBeanNames.DSO_APP_EVENTS); 359 } 360 361 private TCServerActivationListener activationListener; 362 363 public void setActivationListener(TCServerActivationListener listener) { 364 activationListener = listener; 365 } 366 367 private static class NullContext implements ConfigurationContext { 368 369 private final StageManager manager; 370 371 public NullContext(StageManager manager) { 372 this.manager = manager; 373 } 374 375 public TCLogger getLogger(Class clazz) { 376 return TCLogging.getLogger(clazz); 377 } 378 379 public Stage getStage(String name) { 380 return manager.getStage(name); 381 } 382 383 } 384 385 } 386 | Popular Tags |