package voldemort.rest;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import voldemort.common.service.AbstractService;
import voldemort.common.service.ServiceType;
import voldemort.rest.coordinator.config.CoordinatorConfig;
import voldemort.utils.JmxUtils;
public abstract class AbstractRestService extends AbstractService {
private CoordinatorConfig coordinatorConfig = null;
protected ThreadPoolExecutor workerPool = null;
protected final NettyConnectionStats connectionStats;
private ServerBootstrap bootstrap = null;
private Channel channel = null;
private static final Logger logger = Logger.getLogger(AbstractRestService.class);
public AbstractRestService(ServiceType type, CoordinatorConfig config) {
super(type);
this.coordinatorConfig = config;
this.connectionStats = new NettyConnectionStats();
}
abstract protected void initialize();
abstract protected Logger getLogger();
abstract protected ChannelPipelineFactory getPipelineFactory();
abstract protected int getServicePort();
abstract protected String getServiceName();
@Override
protected void startInner() {
initialize();
// Configure the service
this.workerPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();
this.bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), workerPool));
this.bootstrap.setOption("backlog", this.coordinatorConfig.getNettyServerBacklog());
this.bootstrap.setOption("child.tcpNoDelay", true);
this.bootstrap.setOption("child.keepAlive", true);
this.bootstrap.setOption("child.reuseAddress", true);
// Set up the event pipeline factory.
this.bootstrap.setPipelineFactory(getPipelineFactory());
// Assuming JMX is always enabled for service
JmxUtils.registerMbean(this, JmxUtils.createObjectName(JmxUtils.getPackageName(this.getClass()),
JmxUtils.getClassName(this.getClass())));
// Register MBeans for connection stats
JmxUtils.registerMbean(this.connectionStats,
JmxUtils.createObjectName(JmxUtils.getPackageName(this.getClass()),
JmxUtils.getClassName(this.connectionStats.getClass())));
// Bind and start to accept incoming connections.
this.channel = this.bootstrap.bind(new InetSocketAddress(getServicePort()));
logger.info(getServiceName() + " service started on port " + getServicePort());
}
@Override
protected void stopInner() {
if(this.channel != null) {
this.channel.close();
}
JmxUtils.unregisterMbean(JmxUtils.createObjectName(JmxUtils.getPackageName(this.getClass()),
JmxUtils.getClassName(this.getClass())));
}
}