package com.redant.core.server;

import com.redant.common.constants.CommonConstants;
import com.redant.core.handler.ControllerDispatcher;
import com.redant.core.handler.DataStorer;
import com.redant.core.handler.ResponseWriter;
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.HttpServerCodec;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * NettyServer
 * @author gris.wang
 * @create 2017-10-20
 */
public final class NettyServer {

    private final Logger logger = LoggerFactory.getLogger(NettyServer.class);

    public void start() {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.option(ChannelOption.SO_BACKLOG, 1024);
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class)
             .handler(new LoggingHandler(LogLevel.INFO))
             .childHandler(new ServerInitializer());

            ChannelFuture future = b.bind(CommonConstants.SERVER_PORT).sync();
            logger.info("NettyServer Startup at port:{}",CommonConstants.SERVER_PORT);

            // 等待服务端Socket关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            logger.error("InterruptedException:",e);
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private static class ServerInitializer extends ChannelInitializer<SocketChannel> {

        @Override
        public void initChannel(SocketChannel ch) {
            ChannelPipeline p = ch.pipeline();

            // HttpServerCodec is a combination of HttpRequestDecoder and HttpResponseEncoder
            // 使用HttpServerCodec将ByteBuf编解码为httpRequest/httpResponse
            p.addLast(new HttpServerCodec());

            // add gizp compressor for http response content
            p.addLast(new HttpContentCompressor());

            // 指定最大的content_length
            p.addLast(new HttpObjectAggregator(CommonConstants.MAX_CONTENT_LENGTH));

            p.addLast(new ChunkedWriteHandler());

            p.addLast(new DataStorer());

            p.addLast(new ControllerDispatcher());

            p.addLast(new ResponseWriter());

        }
    }

}
@@ -217,24 +217,76 @@
 onseWriter;%0A
+import com.redant.core.interceptor.InterceptorUtil;%0A
 import io.ne
@@ -2685,32 +2685,56 @@
 iteHandler());%0A%0A
+            // %E4%B8%B4%E6%97%B6%E4%BF%9D%E5%AD%98%E8%AF%B7%E6%B1%82%E6%95%B0%E6%8D%AE%0A
             p.ad
@@ -2775,47 +2775,514 @@
     
-p.addLast(new ControllerDispatcher());%0A
+// %E5%89%8D%E7%BD%AE%E6%8B%A6%E6%88%AA%E5%99%A8%0A            ChannelHandler%5B%5D preInterceptors = InterceptorUtil.getPreInterceptors();%0A            if(preInterceptors.length%3E0) %7B%0A                p.addLast(preInterceptors);%0A            %7D%0A%0A            // %E8%B7%AF%E7%94%B1%E5%88%86%E5%8F%91%E5%99%A8%0A            p.addLast(new ControllerDispatcher());%0A%0A            // %E5%90%8E%E7%BD%AE%E6%8B%A6%E6%88%AA%E5%99%A8%0A            ChannelHandler%5B%5D afterInterceptors = InterceptorUtil.getAfterInterceptors();%0A            if(afterInterceptors.length%3E0) %7B%0A                p.addLast(afterInterceptors);%0A            %7D%0A%0A            // %E8%AF%B7%E6%B1%82%E7%BB%93%E6%9E%9C%E5%93%8D%E5%BA%94
 %0A   

add interceptors