package net.iponweb.disthene.reader.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpContentCompressor; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import net.iponweb.disthene.reader.config.ReaderConfiguration; import net.iponweb.disthene.reader.handler.DistheneReaderHandler; import org.apache.log4j.Logger; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; /** * @author Andrei Ivanov */ public class ReaderServer { public static final int MAX_CONTENT_LENGTH = 104857600; private Logger logger = Logger.getLogger(ReaderServer.class); private EventLoopGroup bossGroup = new NioEventLoopGroup(); private EventLoopGroup workerGroup = new NioEventLoopGroup(); private ReaderConfiguration configuration; private Map<Pattern, DistheneReaderHandler> handlers = new HashMap<>(); public ReaderServer(ReaderConfiguration configuration) { this.configuration = configuration; } public void run() throws InterruptedException { bossGroup = new NioEventLoopGroup(configuration.getThreads()); workerGroup = new NioEventLoopGroup(configuration.getThreads()); ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 100) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new HttpRequestDecoder( configuration.getMaxInitialLineLength(), configuration.getMaxHeaderSize(), configuration.getMaxChunkSize() )); p.addLast(new HttpObjectAggregator(MAX_CONTENT_LENGTH)); p.addLast(new HttpResponseEncoder()); p.addLast(new HttpContentCompressor()); p.addLast(new ReaderServerHandler(handlers)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { logger.error(cause); super.exceptionCaught(ctx, cause); } }); // Start the server. b.bind(configuration.getBind(), configuration.getPort()).sync(); } public void registerHandler(String path, DistheneReaderHandler handler) { handlers.put(Pattern.compile(path), handler); } public void shutdown() { logger.info("Shutting down boss group"); bossGroup.shutdownGracefully().awaitUninterruptibly(60000); logger.info("Shutting down worker group"); workerGroup.shutdownGracefully().awaitUninterruptibly(60000); } }