/**
* Dianping.com Inc.
* Copyright (c) 2003-2013 All Rights Reserved.
*/
package com.dianping.pigeon.remoting.http.provider;
import java.util.List;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.log.Logger;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.thread.QueuedThreadPool;
import com.dianping.pigeon.config.ConfigManager;
import com.dianping.pigeon.config.ConfigManagerLoader;
import com.dianping.pigeon.extension.ExtensionLoader;
import com.dianping.pigeon.remoting.common.domain.Disposable;
import com.dianping.pigeon.remoting.common.util.Constants;
import com.dianping.pigeon.remoting.http.HttpUtils;
import com.dianping.pigeon.remoting.provider.AbstractServer;
import com.dianping.pigeon.remoting.provider.config.ProviderConfig;
import com.dianping.pigeon.remoting.provider.config.ServerConfig;
import com.dianping.pigeon.util.NetUtils;
public class JettyHttpServer extends AbstractServer implements Disposable {
protected final Logger logger = LoggerLoader.getLogger(this.getClass());
private Server server;
private int port;
private volatile boolean started = false;
private final ConfigManager configManager = ConfigManagerLoader.getConfigManager();
private final int minThreads = configManager.getIntValue("pigeon.provider.http.minthreads", 2);
private final int maxThreads = configManager.getIntValue("pigeon.provider.http.maxthreads", 300);
public JettyHttpServer() {
}
@Override
public void destroy() throws Exception {
this.stop();
}
@Override
public boolean support(ServerConfig serverConfig) {
if (serverConfig.getProtocol().equals(this.getProtocol())) {
return true;
}
return false;
}
private Server newServer(ServerConfig serverConfig) {
// if (serverConfig.isAutoSelectPort()) {
int availablePort = NetUtils.getAvailablePort(serverConfig.getHttpPort());
this.port = availablePort;
// } else {
// if (NetUtils.isPortInUse(serverConfig.getHttpPort())) {
// logger.error("unable to start jetty server on port " +
// serverConfig.getHttpPort()
// + ", the port is in use");
// System.exit(0);
// }
// this.port = serverConfig.getHttpPort();
// }
DispatcherServlet.addHttpHandler(port, new HttpServerHandler(this));
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setDaemon(true);
threadPool.setMaxThreads(maxThreads);
threadPool.setMinThreads(minThreads);
Server server = new Server(port);
server.setThreadPool(threadPool);
Context context = new Context(Context.SESSIONS);
context.setContextPath("/");
server.addHandler(context);
context.addServlet(new ServletHolder(new DispatcherServlet()), "/service");
List<JettyHttpServerProcessor> processors = ExtensionLoader.getExtensionList(JettyHttpServerProcessor.class);
if (processors != null) {
for (JettyHttpServerProcessor processor : processors) {
processor.preStart(serverConfig, server, context);
}
}
return server;
}
@Override
public void doStart(ServerConfig serverConfig) {
int retries = 0;
while (!started) {
server = newServer(serverConfig);
retries++;
try {
server.start();
serverConfig.setIp(configManager.getLocalIp());
serverConfig.setHttpPort(this.port);
started = true;
} catch (Throwable e) {
if (retries > 5) {
throw new IllegalStateException("failed to start jetty server on " + serverConfig.getHttpPort()
+ ", cause: " + e.getMessage(), e);
}
}
}
}
@Override
public void doStop() {
if (server != null) {
try {
server.stop();
} catch (Throwable e) {
logger.warn(e.getMessage(), e);
}
}
}
@Override
public <T> void doAddService(ProviderConfig<T> providerConfig) {
}
@Override
public <T> void doRemoveService(ProviderConfig<T> providerConfig) {
}
@Override
public String toString() {
return "http server-" + port;
}
@Override
public int getPort() {
return port;
}
@Override
public String getRegistryUrl(String url) {
return HttpUtils.getHttpServiceUrl(url);
}
@Override
public List<String> getInvokerMetaInfo() {
return null;
}
@Override
public boolean isStarted() {
return started;
}
@Override
public String getProtocol() {
return Constants.PROTOCOL_HTTP;
}
}