Search in sources :

Example 56 with GenericFutureListener

use of io.netty.util.concurrent.GenericFutureListener in project jersey by eclipse-ee4j.

the class NettyConnector method execute.

protected CompletableFuture<ClientResponse> execute(final ClientRequest jerseyRequest) {
    Integer timeout = jerseyRequest.resolveProperty(ClientProperties.READ_TIMEOUT, 0);
    if (timeout == null || timeout < 0) {
        throw new ProcessingException(LocalizationMessages.WRONG_READ_TIMEOUT(timeout));
    }
    final CompletableFuture<ClientResponse> responseAvailable = new CompletableFuture<>();
    final CompletableFuture<?> responseDone = new CompletableFuture<>();
    final URI requestUri = jerseyRequest.getUri();
    String host = requestUri.getHost();
    int port = requestUri.getPort() != -1 ? requestUri.getPort() : "https".equals(requestUri.getScheme()) ? 443 : 80;
    try {
        String key = requestUri.getScheme() + "://" + host + ":" + port;
        ArrayList<Channel> conns;
        synchronized (connections) {
            conns = connections.get(key);
            if (conns == null) {
                conns = new ArrayList<>(0);
                connections.put(key, conns);
            }
        }
        Channel chan = null;
        synchronized (conns) {
            while (chan == null && !conns.isEmpty()) {
                chan = conns.remove(conns.size() - 1);
                try {
                    chan.pipeline().remove(INACTIVE_POOLED_CONNECTION_HANDLER);
                    chan.pipeline().remove(PRUNE_INACTIVE_POOL);
                } catch (NoSuchElementException e) {
                /*
                       *  Eat it.
                       *  It could happen that the channel was closed, pipeline cleared and
                       *  then it will fail to remove the names with this exception.
                       */
                }
                if (!chan.isOpen()) {
                    chan = null;
                }
            }
        }
        if (chan == null) {
            Bootstrap b = new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline p = ch.pipeline();
                    // Enable HTTPS if necessary.
                    if ("https".equals(requestUri.getScheme())) {
                        // making client authentication optional for now; it could be extracted to configurable property
                        JdkSslContext jdkSslContext = new JdkSslContext(client.getSslContext(), true, ClientAuth.NONE);
                        p.addLast(jdkSslContext.newHandler(ch.alloc()));
                    }
                    // http proxy
                    Configuration config = jerseyRequest.getConfiguration();
                    final Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
                    if (proxyUri != null) {
                        final URI u = getProxyUri(proxyUri);
                        final String userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
                        final String password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
                        p.addLast(new HttpProxyHandler(new InetSocketAddress(u.getHost(), u.getPort() == -1 ? 8080 : u.getPort()), userName, password));
                    }
                    p.addLast(new HttpClientCodec());
                    p.addLast(new ChunkedWriteHandler());
                    p.addLast(new HttpContentDecompressor());
                }
            });
            // connect timeout
            Integer connectTimeout = jerseyRequest.resolveProperty(ClientProperties.CONNECT_TIMEOUT, 0);
            if (connectTimeout > 0) {
                b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
            }
            // Make the connection attempt.
            chan = b.connect(host, port).sync().channel();
        }
        // assert: clientHandler will always notify responseDone: either normally, or exceptionally
        // assert: clientHandler may notify responseAvailable, if sufficient parts of response are detected to construct
        // a valid ClientResponse
        // assert: responseAvailable completion may be racing against responseDone completion
        // assert: it is ok to abort the entire response, if responseDone is completed exceptionally - in particular, nothing
        // will leak
        final Channel ch = chan;
        JerseyClientHandler clientHandler = new JerseyClientHandler(jerseyRequest, responseAvailable, responseDone);
        // read timeout makes sense really as an inactivity timeout
        ch.pipeline().addLast(READ_TIMEOUT_HANDLER, new IdleStateHandler(0, 0, timeout, TimeUnit.MILLISECONDS));
        ch.pipeline().addLast(REQUEST_HANDLER, clientHandler);
        responseDone.whenComplete((_r, th) -> {
            ch.pipeline().remove(READ_TIMEOUT_HANDLER);
            ch.pipeline().remove(clientHandler);
            if (th == null) {
                ch.pipeline().addLast(INACTIVE_POOLED_CONNECTION_HANDLER, new IdleStateHandler(0, 0, maxPoolIdle));
                ch.pipeline().addLast(PRUNE_INACTIVE_POOL, new PruneIdlePool(connections, key));
                boolean added = true;
                synchronized (connections) {
                    ArrayList<Channel> conns1 = connections.get(key);
                    if (conns1 == null) {
                        conns1 = new ArrayList<>(1);
                        conns1.add(ch);
                        connections.put(key, conns1);
                    } else {
                        synchronized (conns1) {
                            if ((maxPoolSizeTotal == 0 || connections.size() < maxPoolSizeTotal) && conns1.size() < maxPoolSize) {
                                conns1.add(ch);
                            } else {
                                // else do not add the Channel to the idle pool
                                added = false;
                            }
                        }
                    }
                }
                if (!added) {
                    ch.close();
                }
            } else {
                ch.close();
                // if responseAvailable has been completed, no-op: jersey will encounter IOException while reading response body
                // if responseAvailable has not been completed, abort
                responseAvailable.completeExceptionally(th);
            }
        });
        HttpRequest nettyRequest;
        String pathWithQuery = buildPathWithQueryParameters(requestUri);
        if (jerseyRequest.hasEntity()) {
            nettyRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(jerseyRequest.getMethod()), pathWithQuery);
        } else {
            nettyRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(jerseyRequest.getMethod()), pathWithQuery);
        }
        // headers
        for (final Map.Entry<String, List<String>> e : jerseyRequest.getStringHeaders().entrySet()) {
            nettyRequest.headers().add(e.getKey(), e.getValue());
        }
        // host header - http 1.1
        nettyRequest.headers().add(HttpHeaderNames.HOST, jerseyRequest.getUri().getHost());
        if (jerseyRequest.hasEntity()) {
            // guard against prematurely closed channel
            final GenericFutureListener<io.netty.util.concurrent.Future<? super Void>> closeListener = new GenericFutureListener<io.netty.util.concurrent.Future<? super Void>>() {

                @Override
                public void operationComplete(io.netty.util.concurrent.Future<? super Void> future) throws Exception {
                    if (!responseDone.isDone()) {
                        responseDone.completeExceptionally(new IOException("Channel closed."));
                    }
                }
            };
            ch.closeFuture().addListener(closeListener);
            if (jerseyRequest.getLengthLong() == -1) {
                HttpUtil.setTransferEncodingChunked(nettyRequest, true);
            } else {
                nettyRequest.headers().add(HttpHeaderNames.CONTENT_LENGTH, jerseyRequest.getLengthLong());
            }
            // Send the HTTP request.
            ch.writeAndFlush(nettyRequest);
            final JerseyChunkedInput jerseyChunkedInput = new JerseyChunkedInput(ch);
            jerseyRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {

                @Override
                public OutputStream getOutputStream(int contentLength) throws IOException {
                    return jerseyChunkedInput;
                }
            });
            if (HttpUtil.isTransferEncodingChunked(nettyRequest)) {
                ch.write(new HttpChunkedInput(jerseyChunkedInput));
            } else {
                ch.write(jerseyChunkedInput);
            }
            executorService.execute(new Runnable() {

                @Override
                public void run() {
                    // close listener is not needed any more.
                    ch.closeFuture().removeListener(closeListener);
                    try {
                        jerseyRequest.writeEntity();
                    } catch (IOException e) {
                        responseDone.completeExceptionally(e);
                    }
                }
            });
            ch.flush();
        } else {
            // Send the HTTP request.
            ch.writeAndFlush(nettyRequest);
        }
    } catch (InterruptedException e) {
        responseDone.completeExceptionally(e);
    }
    return responseAvailable;
}
Also used : SocketChannel(io.netty.channel.socket.SocketChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Configuration(javax.ws.rs.core.Configuration) InetSocketAddress(java.net.InetSocketAddress) OutputStream(java.io.OutputStream) HttpClientCodec(io.netty.handler.codec.http.HttpClientCodec) List(java.util.List) ArrayList(java.util.ArrayList) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener) ProcessingException(javax.ws.rs.ProcessingException) SocketChannel(io.netty.channel.socket.SocketChannel) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) Channel(io.netty.channel.Channel) HttpProxyHandler(io.netty.handler.proxy.HttpProxyHandler) Map(java.util.Map) HashMap(java.util.HashMap) ClientResponse(org.glassfish.jersey.client.ClientResponse) URI(java.net.URI) OutboundMessageContext(org.glassfish.jersey.message.internal.OutboundMessageContext) CompletableFuture(java.util.concurrent.CompletableFuture) HttpChunkedInput(io.netty.handler.codec.http.HttpChunkedInput) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) Bootstrap(io.netty.bootstrap.Bootstrap) JerseyChunkedInput(org.glassfish.jersey.netty.connector.internal.JerseyChunkedInput) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) DefaultHttpRequest(io.netty.handler.codec.http.DefaultHttpRequest) HttpRequest(io.netty.handler.codec.http.HttpRequest) JdkSslContext(io.netty.handler.ssl.JdkSslContext) DefaultFullHttpRequest(io.netty.handler.codec.http.DefaultFullHttpRequest) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) ProcessingException(javax.ws.rs.ProcessingException) NoSuchElementException(java.util.NoSuchElementException) IOException(java.io.IOException) ChannelPipeline(io.netty.channel.ChannelPipeline) HttpContentDecompressor(io.netty.handler.codec.http.HttpContentDecompressor) NioSocketChannel(io.netty.channel.socket.nio.NioSocketChannel) ChunkedWriteHandler(io.netty.handler.stream.ChunkedWriteHandler) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) Future(java.util.concurrent.Future) CompletableFuture(java.util.concurrent.CompletableFuture) NoSuchElementException(java.util.NoSuchElementException)

Example 57 with GenericFutureListener

use of io.netty.util.concurrent.GenericFutureListener in project SMSGate by Lihuanghe.

the class SessionConnectedHandler method userEventTriggered.

@Override
public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) throws Exception {
    final AtomicInteger tmptotal = totleCnt;
    if (evt == SessionState.Connect) {
        final Channel ch = ctx.channel();
        EventLoopGroupFactory.INS.submitUnlimitCircleTask(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                int cnt = RandomUtils.nextInt() & 0x4fff;
                Promise<BaseMessage> frefuture = null;
                while (cnt > 0 && tmptotal.get() > 0) {
                    List<Promise<BaseMessage>> futures = null;
                    ChannelFuture chfuture = null;
                    BaseMessage msg = createTestReq(UUID.randomUUID().toString());
                    // chfuture = ChannelUtil.asyncWriteToEntity(getEndpointEntity().getId(), msg);
                    futures = ChannelUtil.syncWriteLongMsgToEntity(getEndpointEntity().getId(), msg);
                    if (chfuture != null)
                        chfuture.sync();
                    cnt--;
                    tmptotal.decrementAndGet();
                    if (futures != null) {
                        try {
                            for (Promise<BaseMessage> future : futures) {
                                future.addListener(new GenericFutureListener<Future<BaseMessage>>() {

                                    @Override
                                    public void operationComplete(Future<BaseMessage> future) throws Exception {
                                        if (future.isSuccess()) {
                                        // logger.info("response:{}",future.get());
                                        } else {
                                        // logger.error("response:{}",future.cause());
                                        }
                                    }
                                });
                                frefuture = future;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            cnt--;
                            tmptotal.decrementAndGet();
                            break;
                        }
                    } else {
                        // 连接不可写了,等待上一个response回来
                        // 再把消息发出去
                        ctx.writeAndFlush(msg);
                        if (frefuture != null) {
                            frefuture.sync();
                            frefuture = null;
                        } else {
                            break;
                        }
                    }
                }
                return true;
            }
        }, new ExitUnlimitCirclePolicy<Boolean>() {

            @Override
            public boolean notOver(Future<Boolean> future) {
                if (future.cause() != null)
                    future.cause().printStackTrace();
                boolean over = ch.isActive() && tmptotal.get() > 0;
                if (!over) {
                    logger.info("========send over.============");
                // ch.writeAndFlush(new CmppTerminateRequestMessage());
                }
                return over;
            }
        }, 1);
    }
    ctx.fireUserEventTriggered(evt);
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) Promise(io.netty.util.concurrent.Promise) BaseMessage(com.zx.sms.BaseMessage) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) List(java.util.List) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener)

Example 58 with GenericFutureListener

use of io.netty.util.concurrent.GenericFutureListener in project SMSGate by Lihuanghe.

the class SessionLoginManager method failedLogin.

@Override
protected /**
 * 状态 0:正确 1:消息结构错 2:非法源地址 3:认证错 4:版本太高 5~ :其他错误
 */
void failedLogin(ChannelHandlerContext ctx, Object msg, long status) {
    if (msg instanceof CmppConnectRequestMessage) {
        logger.error("Connected error status :{},msg : {}", status, msg);
        CmppConnectRequestMessage message = (CmppConnectRequestMessage) msg;
        // 认证失败
        CmppConnectResponseMessage resp = new CmppConnectResponseMessage(message.getHeader().getSequenceId());
        resp.setAuthenticatorISMG(new byte[16]);
        resp.setStatus(status);
        ChannelFuture promise = ctx.writeAndFlush(resp);
        final ChannelHandlerContext finalctx = ctx;
        promise.addListener(new GenericFutureListener() {

            public void operationComplete(Future future) throws Exception {
                finalctx.close();
            }
        });
    } else {
        logger.error("connect msg type error : {}", msg);
        ctx.close();
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CmppConnectRequestMessage(com.zx.sms.codec.cmpp.msg.CmppConnectRequestMessage) CmppConnectResponseMessage(com.zx.sms.codec.cmpp.msg.CmppConnectResponseMessage) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener)

Example 59 with GenericFutureListener

use of io.netty.util.concurrent.GenericFutureListener in project SMSGate by Lihuanghe.

the class SgipSessionLoginManager method failedLogin.

@Override
protected void failedLogin(ChannelHandlerContext ctx, Object msg, long status) {
    if (msg instanceof SgipBindRequestMessage) {
        logger.error("Connected error status :{},msg : {}", status, msg);
        SgipBindRequestMessage message = (SgipBindRequestMessage) msg;
        // 认证失败
        SgipBindResponseMessage resp = new SgipBindResponseMessage(((Message) message).getHeader());
        resp.setResult((short) status);
        resp.setTimestamp(((Message) message).getTimestamp());
        ChannelFuture promise = ctx.writeAndFlush(resp);
        final ChannelHandlerContext finalctx = ctx;
        promise.addListener(new GenericFutureListener() {

            public void operationComplete(Future future) throws Exception {
                finalctx.close();
            }
        });
    } else {
        logger.error("connect msg type error : {}", msg);
        ctx.close();
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) SgipBindResponseMessage(com.zx.sms.codec.sgip12.msg.SgipBindResponseMessage) SgipBindRequestMessage(com.zx.sms.codec.sgip12.msg.SgipBindRequestMessage) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener)

Example 60 with GenericFutureListener

use of io.netty.util.concurrent.GenericFutureListener in project SMSGate by Lihuanghe.

the class SMGPSessionLoginManager method failedLogin.

@Override
protected void failedLogin(ChannelHandlerContext ctx, Object msg, long status) {
    if (msg instanceof SMGPLoginMessage) {
        logger.error("Connected error status :{},msg : {}", status, msg);
        SMGPLoginMessage message = (SMGPLoginMessage) msg;
        // 认证失败
        SMGPLoginRespMessage resp = new SMGPLoginRespMessage();
        resp.setSequenceNo(message.getSequenceNo());
        resp.setStatus((int) status);
        ChannelFuture promise = ctx.writeAndFlush(resp);
        final ChannelHandlerContext finalctx = ctx;
        promise.addListener(new GenericFutureListener() {

            public void operationComplete(Future future) throws Exception {
                finalctx.close();
            }
        });
    } else {
        logger.error("connect msg type error : {}", msg);
        ctx.close();
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) SMGPLoginRespMessage(com.zx.sms.codec.smgp.msg.SMGPLoginRespMessage) SMGPLoginMessage(com.zx.sms.codec.smgp.msg.SMGPLoginMessage) ChannelFuture(io.netty.channel.ChannelFuture) Future(io.netty.util.concurrent.Future) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener)

Aggregations

GenericFutureListener (io.netty.util.concurrent.GenericFutureListener)70 Future (io.netty.util.concurrent.Future)44 ChannelFuture (io.netty.channel.ChannelFuture)32 Channel (io.netty.channel.Channel)19 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)18 IOException (java.io.IOException)18 List (java.util.List)15 InetSocketAddress (java.net.InetSocketAddress)13 ArrayList (java.util.ArrayList)13 Map (java.util.Map)12 ChannelOption (io.netty.channel.ChannelOption)10 Future (io.vertx.core.Future)10 Handler (io.vertx.core.Handler)10 ContextInternal (io.vertx.core.impl.ContextInternal)10 VertxInternal (io.vertx.core.impl.VertxInternal)10 Logger (org.slf4j.Logger)10 LoggerFactory (org.slf4j.LoggerFactory)9 Bootstrap (io.netty.bootstrap.Bootstrap)8 LoggingHandler (io.netty.handler.logging.LoggingHandler)8 AsyncResult (io.vertx.core.AsyncResult)8