package ddth.dasp.hetty.front;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.StringUtils;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerBossPool;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioWorkerPool;
import org.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.ThreadNameDeterminer;
import org.jboss.netty.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ddth.dasp.common.DaspGlobal;
import ddth.dasp.common.config.IConfigDao;
import ddth.dasp.hetty.HettyConstants;
import ddth.dasp.hetty.message.IMessageFactory;
import ddth.dasp.hetty.qnt.IQueueWriter;
import ddth.dasp.hetty.utils.HettyControlPanelHttp;
import ddth.dasp.hetty.utils.HettyUtils;
import ddth.dasp.servlet.utils.NetUtils;
public class HettyConnServer {
private final Logger LOGGER = LoggerFactory.getLogger(HettyConnServer.class);
private IQueueWriter queueWriter;
private IMessageFactory messageFactory;
private long readTimeoutMillisecs = 10000, writeTimeoutMillisecs = 10000;
private int numWorkers = 32;
private String portStr = "8083";
private Timer timer;
private ServerBootstrap nettyServer;
private static HettyPipelineFactory hettyPipelineFactory;
private static Map<String, Object> hostQueueNameMapping = new ConcurrentHashMap<String, Object>();
public static Map<String, Object> getHostQueueNameMapping() {
return hostQueueNameMapping;
}
public static void setHostQueueNameMapping(Map<String, Object> hostQueueNameMapping) {
HettyConnServer.hostQueueNameMapping = hostQueueNameMapping;
}
public static void addHostQueueNameMapping(String host, Object mapping) {
hostQueueNameMapping.put(host, mapping);
}
public static void deleteHostQueueNameMapping(String host) {
hostQueueNameMapping.remove(host);
}
public HettyConnServer() {
}
public IQueueWriter getQueueWriter() {
return queueWriter;
}
public HettyConnServer setQueueWriter(IQueueWriter queueWriter) {
this.queueWriter = queueWriter;
return this;
}
public IMessageFactory getMessageFactory() {
return messageFactory;
}
public HettyConnServer setMessageFactory(IMessageFactory messageFactory) {
this.messageFactory = messageFactory;
return this;
}
public long getReadTimeoutMillisecs() {
return readTimeoutMillisecs;
}
public HettyConnServer setReadTimeoutMillisecs(long readTimeoutMillisecs) {
this.readTimeoutMillisecs = readTimeoutMillisecs;
return this;
}
public long getWriteTimeoutMillisecs() {
return writeTimeoutMillisecs;
}
public HettyConnServer setWriteTimeoutMillisecs(long writeTimeoutMillisecs) {
this.writeTimeoutMillisecs = writeTimeoutMillisecs;
return this;
}
public int getNumWorkers() {
return numWorkers;
}
public HettyConnServer setNumWorkers(int numWorkers) {
this.numWorkers = numWorkers;
return this;
}
public String getPort() {
return portStr;
}
public HettyConnServer setPort(String portStr) {
this.portStr = portStr;
return this;
}
@SuppressWarnings("unchecked")
public void init() {
IConfigDao configDao = DaspGlobal.getOsgiBootstrap().getService(IConfigDao.class);
hostQueueNameMapping = (Map<String, Object>) configDao.getConfig(
HettyControlPanelHttp.MODULE, HettyControlPanelHttp.CONFIG_KEY);
if (hostQueueNameMapping == null || hostQueueNameMapping.size() == 0) {
hostQueueNameMapping = new ConcurrentHashMap<String, Object>();
hostQueueNameMapping.put("127.0.0.1", HettyConstants.DEFAULT_HETTY_QUEUE);
hostQueueNameMapping.put("localhost", HettyConstants.DEFAULT_HETTY_QUEUE);
configDao.setConfig(HettyControlPanelHttp.MODULE, HettyControlPanelHttp.CONFIG_KEY,
hostQueueNameMapping);
}
Integer port = 8083;
if (!StringUtils.isBlank(portStr)) {
// find free port
String[] tokens = portStr.split("[\\s,]+");
int[] ports = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
ports[i] = Integer.parseInt(tokens[i]);
}
port = NetUtils.getFreePort(ports);
}
timer = new HashedWheelTimer(Executors.defaultThreadFactory(), 10, TimeUnit.MILLISECONDS,
8192);
NioServerBossPool serverBossPool = new NioServerBossPool(Executors.newCachedThreadPool(),
1, new ThreadNameDeterminer() {
private AtomicInteger COUNTER = new AtomicInteger(1);
@Override
public String determineThreadName(String currentThreadName,
String proposedThreadName) throws Exception {
int counter = COUNTER.getAndIncrement();
return "Hetty server boss #" + counter;
}
});
NioWorkerPool workerPool = new NioWorkerPool(Executors.newCachedThreadPool(), numWorkers,
new ThreadNameDeterminer() {
private AtomicInteger COUNTER = new AtomicInteger(1);
@Override
public String determineThreadName(String currentThreadName,
String proposedThreadName) throws Exception {
int counter = COUNTER.getAndIncrement();
return "Hetty worker #" + counter;
}
});
nettyServer = new ServerBootstrap(new NioServerSocketChannelFactory(serverBossPool,
workerPool));
if (hettyPipelineFactory == null) {
hettyPipelineFactory = new HettyPipelineFactory(queueWriter, messageFactory, timer,
readTimeoutMillisecs, writeTimeoutMillisecs);
}
nettyServer.setPipelineFactory(hettyPipelineFactory);
nettyServer.setOption("child.tcpNoDelay", true);
nettyServer.setOption("child.keepAlive", false);
nettyServer.bind(new InetSocketAddress(port));
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Hetty interface is listening on port: " + port + " / Read timeout: "
+ readTimeoutMillisecs + " / Write timeout: " + writeTimeoutMillisecs
+ " / Num workers: " + numWorkers);
}
}
public void destroy() {
try {
if (nettyServer != null) {
nettyServer.releaseExternalResources();
}
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
}
try {
if (timer != null) {
timer.stop();
}
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
}
try {
HettyUtils.ALL_CHANNELS.close();
} catch (Exception e) {
LOGGER.warn(e.getMessage(), e);
}
}
}