class Netty4HttpServer extends AbstractServer implements StatisticCallback {
    private HttpMessageHandler httpMessageHandler;
    private URL url;
    private Channel channel;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private StandardThreadExecutor standardThreadExecutor;

    public Netty4HttpServer(URL url, HttpMessageHandler httpMessageHandler) {
        this.url = url;
        this.httpMessageHandler = httpMessageHandler;
    }

    @Override
    public synchronized boolean open() {
        if (isAvailable()) {
            return true;
        }
        if (channel != null) {
            channel.close();
        }
        if (bossGroup == null) {
            bossGroup = new NioEventLoopGroup();
            workerGroup = new NioEventLoopGroup();
        }
        boolean shareChannel = url.getBooleanParameter(URLParamType.shareChannel.getName(), URLParamType.shareChannel.getBooleanValue());
        int workerQueueSize = url.getIntParameter(URLParamType.workerQueueSize.getName(), 500);

        int minWorkerThread, maxWorkerThread;

        if (shareChannel) {
            minWorkerThread = url.getIntParameter(URLParamType.minWorkerThread.getName(), MotanConstants.NETTY_SHARECHANNEL_MIN_WORKDER);
            maxWorkerThread = url.getIntParameter(URLParamType.maxWorkerThread.getName(), MotanConstants.NETTY_SHARECHANNEL_MAX_WORKDER);
        } else {
            minWorkerThread =
                    url.getIntParameter(URLParamType.minWorkerThread.getName(), MotanConstants.NETTY_NOT_SHARECHANNEL_MIN_WORKDER);
            maxWorkerThread =
                    url.getIntParameter(URLParamType.maxWorkerThread.getName(), MotanConstants.NETTY_NOT_SHARECHANNEL_MAX_WORKDER);
        }
        final int maxContentLength = url.getIntParameter(URLParamType.maxContentLength.getName(), URLParamType.maxContentLength.getIntValue());
        standardThreadExecutor = (standardThreadExecutor != null && !standardThreadExecutor.isShutdown()) ? standardThreadExecutor
                : new StandardThreadExecutor(minWorkerThread, maxWorkerThread, workerQueueSize, new DefaultThreadFactory("NettyServer-" + url.getServerPortStr(), true));
        standardThreadExecutor.prestartAllCoreThreads();

        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) {
                ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
                ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(maxContentLength));
                ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
                ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
                ch.pipeline().addLast("serverHandler", new SimpleChannelInboundHandler<FullHttpRequest>() {
                    protected void channelRead0(final ChannelHandlerContext ctx, final FullHttpRequest httpRequest) {
                        httpRequest.content().retain();
                        try {
                            standardThreadExecutor.execute(() -> processHttpRequest(ctx, httpRequest));
                        } catch (Exception e) {
                            LoggerUtil.error("request is rejected by threadPool!", e);
                            httpRequest.content().release();
                            sendResponse(ctx, NettyHttpUtil.buildErrorResponse("request is rejected by thread pool!"));
                        }
                    }
                });
            }
        }).option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, false);

        ChannelFuture f;
        try {
            f = b.bind(url.getPort()).sync();
            channel = f.channel();
        } catch (InterruptedException e) {
            LoggerUtil.error("init http server fail.", e);
            return false;
        }
        setLocalAddress((InetSocketAddress) channel.localAddress());
        if (url.getPort() == 0) {
            url.setPort(getLocalAddress().getPort());
        }
        state = ChannelState.ALIVE;
        StatsUtil.registryStatisticCallback(this);
        LoggerUtil.info("Netty4HttpServer ServerChannel finish Open: url=" + url);
        return true;
    }

    private void processHttpRequest(ChannelHandlerContext ctx, FullHttpRequest httpRequest) {
        FullHttpResponse httpResponse;
        try {
            httpRequest.headers().set(URLParamType.host.getName(), ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress());
            httpResponse = httpMessageHandler.handle(this, httpRequest);
        } catch (Exception e) {
            LoggerUtil.error("NettyHttpHandler process http request fail.", e);
            httpResponse = NettyHttpUtil.buildErrorResponse(e.getMessage());
        } finally {
            httpRequest.content().release();
        }
        sendResponse(ctx, httpResponse);
    }

    private void sendResponse(ChannelHandlerContext ctx, FullHttpResponse httpResponse) {
        boolean close = false;
        try {
            ctx.write(httpResponse);
            ctx.flush();
        } catch (Exception e) {
            LoggerUtil.error("NettyHttpHandler write response fail.", e);
            close = true;
        } finally {
            // close connection
            if (close || httpResponse == null || !httpResponse.headers().contains(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE, true)) {
                ctx.close();
            }
        }
    }

    @Override
    public void close() {
        close(0);
    }

    @Override
    public boolean isAvailable() {
        return state.isAliveState();
    }

    @Override
    public boolean isBound() {
        return channel != null && channel.isActive();
    }

    @Override
    public Response request(Request request) throws TransportException {<FILL_FUNCTION_BODY>}

    @Override
    public synchronized void close(int timeout) {
        if (state.isCloseState()) {
            LoggerUtil.info("Netty4HttpServer close fail: already close, url={}", url.getUri());
            return;
        }

        if (state.isUnInitState()) {
            LoggerUtil.info("Netty4HttpServer close Fail: don't need to close because node is unInit state: url={}",
                    url.getUri());
            return;
        }
        if (channel != null) {
            channel.close();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
        if (standardThreadExecutor != null) {
            standardThreadExecutor.shutdownNow();
        }
        workerGroup = null;
        bossGroup = null;
        standardThreadExecutor = null;
        channel = null;
        state = ChannelState.CLOSE;
        StatsUtil.unRegistryStatisticCallback(this);
    }

    @Override
    public boolean isClosed() {
        return state.isCloseState();
    }

    @Override
    public String statisticCallback() {
        return null;
    }

    @Override
    public URL getUrl() {
        return url;
    }

}

        throw new MotanFrameworkException("Netty4HttpServer request(Request request) method unSupport: url: " + url);
    
<methods>public void <init>() ,public void <init>(com.weibo.api.motan.rpc.URL) ,public com.weibo.api.motan.transport.Channel getChannel(java.net.InetSocketAddress) ,public Collection<com.weibo.api.motan.transport.Channel> getChannels() ,public java.net.InetSocketAddress getLocalAddress() ,public java.net.InetSocketAddress getRemoteAddress() ,public Map<java.lang.String,java.lang.Object> getRuntimeInfo() ,public void setCodec(com.weibo.api.motan.codec.Codec) ,public void setLocalAddress(java.net.InetSocketAddress) ,public void setRemoteAddress(java.net.InetSocketAddress) ,public void setUrl(com.weibo.api.motan.rpc.URL) <variables>protected com.weibo.api.motan.codec.Codec codec,protected java.net.InetSocketAddress localAddress,protected java.net.InetSocketAddress remoteAddress,protected volatile com.weibo.api.motan.common.ChannelState state,protected com.weibo.api.motan.rpc.URL url