package org.async.rmi.netty; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import org.async.rmi.Connection; import org.async.rmi.Factory; import org.async.rmi.Modules; import org.async.rmi.TimeSpan; import org.async.rmi.client.RemoteObjectAddress; import org.async.rmi.messages.Message; import org.async.rmi.pool.Pool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.TimeoutException; /** * Created by Barak Bar Orion * 27/10/14. */ public class NettyClientConnectionFactory implements Factory<CompletableFuture<Connection<Message>>> { @SuppressWarnings("UnusedDeclaration") private static final Logger logger = LoggerFactory.getLogger(NettyClientConnectionFactory.class); private final Bootstrap bootstrap; private final RemoteObjectAddress address; private Pool<Connection<Message>> pool; public NettyClientConnectionFactory(final EventLoopGroup group, final RemoteObjectAddress address, final UUID clientId) { this.address = address; bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast( new HandshakeMessageDecoder(), new ClientHandshakeHandler(clientId), new MessageEncoder(), new MessageDecoder(), new RMIClientHandler()); } }); } public void setPool(Pool<Connection<Message>> pool) { this.pool = pool; } @Override public CompletableFuture<Connection<Message>> create() { TimeSpan clientConnectTimeout = Modules.getInstance().getConfiguration().getClientConnectTimeout(); final NettyClientConnection connection = new NettyClientConnection(bootstrap, address, pool); final CompletableFuture<Connection<Message>> res = connection.connect(); ForkJoinPool.commonPool().execute(() -> { try { res.get(clientConnectTimeout.getTime(), clientConnectTimeout.getTimeUnit()); } catch (ExecutionException e) { res.completeExceptionally(e.getCause()); } catch (InterruptedException | TimeoutException e) { res.completeExceptionally(e); } }); return res; } }