All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bdware.irp3.client.ClientBootstrapInitializerFactory Maven / Gradle / Ivy

package org.bdware.irp3.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.ssl.SslHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.irp3.codec.*;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class ClientBootstrapInitializerFactory {
    public static EventLoopGroup workerGroup = new NioEventLoopGroup(new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = Executors.defaultThreadFactory().newThread(r);
            t.setDaemon(true);
            return t;
        }
    });
    static int maxFrame = 5 * 1024 * 1024;

    public static ClientBootstrapInitializer createServerBootstrapInitializer(ClientConfig config) {
        switch (config.uri.getScheme().toLowerCase()) {
            case "udp":
                return new UdpInitializer(config);
            case "tcp":
                return new TcpInitializer(config);
            case "ws":
                return new WSInitializer(config);
            case "tls":
                return new TLSInitializer(config);
            case "http":
            default:
                throw new IllegalStateException("unsupported protocol:" + config.uri.getScheme());
        }
    }

    static class TcpInitializer implements ClientBootstrapInitializer {
        ClientConfig config;

        public TcpInitializer(ClientConfig listenerInfo) {
            this.config = listenerInfo;
        }

        @Override
        public void init(Bootstrap b, ClientHandler handler) {
            b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.group(workerGroup);
            b.channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(
                            new ChannelInitializer() {
                                @Override
                                protected void initChannel(SocketChannel ch) {
                                    ChannelPipeline p = ch.pipeline();
                                    p.addLast(new LengthFieldBasedFrameDecoder(maxFrame, 16, 4, 0, 0))
                                            .addLast(new IrpMessageCodec())
                                            .addLast(new ResponseCodec())
                                            .addLast(handler);
                                }
                            });
        }
    }

    static class UdpInitializer implements ClientBootstrapInitializer {
        ClientConfig config;

        public UdpInitializer(ClientConfig listenerInfo) {
            this.config = listenerInfo;
        }

        @Override
        public void init(Bootstrap b, ClientHandler handler) {
            b.option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                    new WriteBufferWaterMark(10, 100));
            b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
            b.group(workerGroup);
            b.channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(
                            new ChannelInitializer() {
                                @Override
                                protected void initChannel(DatagramChannel ch) {
                                    ChannelPipeline p = ch.pipeline();
                                    p.addLast(new DatagramPacketToIrpMessageCodec(config.uri.getHost(), config.uri.getPort()))
                                            .addLast(new ResponseCodec())
                                            .addLast(handler);
                                }
                            });
        }
    }

    static class TLSInitializer implements ClientBootstrapInitializer {
        ClientConfig info;
        static Logger LOGGER = LogManager.getLogger(TLSInitializer.class);

        public TLSInitializer(ClientConfig listenerInfo) {
            this.info = listenerInfo;
        }


        @Override
        public void init(Bootstrap b, ClientHandler handler) {
            b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
            b.option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                            new WriteBufferWaterMark(1024 * 1024, 20 * 1024 * 1024))
                    .option(ChannelOption.SO_REUSEADDR, true)
                    .option(ChannelOption.SO_LINGER, 0);
            b.group(workerGroup);
            TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    LOGGER.debug(
                            "[TLSClientConfig] UNKNOWN CLIENT CERTIFICATE: " + chain[0].getSubjectDN());
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    LOGGER.debug("UNKNOWN SERVER CERTIFICATE: " + chain[0].getSubjectDN());
                }
            };
            b.channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(
                            new ChannelInitializer() {
                                @Override
                                protected void initChannel(SocketChannel ch) {
                                    ChannelPipeline p = ch.pipeline();
                                    SSLEngine engine = null;
                                    try {
                                        SSLContext clientContext = SSLContext.getInstance("TLS");
                                        clientContext.init(null, new TrustManager[]{DUMMY_TRUST_MANAGER}, null);
                                        engine = clientContext.createSSLEngine();
                                        engine.setUseClientMode(true);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    p.addFirst("ssl", new SslHandler(engine))
                                            .addLast(new LengthFieldBasedFrameDecoder(maxFrame, 16, 4, 0, 0))
                                            .addLast(new IrpMessageCodec())
                                            .addLast(new ResponseCodec())
                                            .addLast(handler);
                                }
                            });
        }
    }

    static class WSInitializer implements ClientBootstrapInitializer {
        ClientConfig info;

        public WSInitializer(ClientConfig listenerInfo) {
            this.info = listenerInfo;
        }

        @Override
        public void init(Bootstrap b, ClientHandler handler) {
            b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
            b.option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                    new WriteBufferWaterMark(1024 * 1024, 20 * 1024 * 1024));
            b.group(workerGroup);
            b.channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(
                            new ChannelInitializer() {
                                @Override
                                protected void initChannel(SocketChannel ch) {
                                    ChannelPipeline p = ch.pipeline();
                                    WebSocketClientProtocolHandler wsClientHandler = new WebSocketClientProtocolHandler(
                                            WebSocketClientHandshakerFactory.newHandshaker(info.uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders()));
                                    p.addLast(new HttpClientCodec())
                                            .addLast(new HttpObjectAggregator(maxFrame))
                                            .addLast(wsClientHandler)
                                            .addLast(new WebSocketFrameToByteBufCodec())
                                            .addLast(new LengthFieldBasedFrameDecoder(maxFrame, 16, 4, 0, 0))
                                            .addLast(new IrpMessageCodec())
                                            .addLast(new ResponseCodec())
                                            .addLast(handler);
                                }
                            });
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy