Example usage for org.apache.http.nio.protocol BasicAsyncResponseConsumer BasicAsyncResponseConsumer

List of usage examples for org.apache.http.nio.protocol BasicAsyncResponseConsumer BasicAsyncResponseConsumer

Introduction

In this page you can find the example usage for org.apache.http.nio.protocol BasicAsyncResponseConsumer BasicAsyncResponseConsumer.

Prototype

public BasicAsyncResponseConsumer() 

Source Link

Usage

From source file:com.yulore.demo.NHttpClient.java

public static void main(String[] args) throws Exception {
    // Create HTTP protocol processing chain
    HttpProcessor httpproc = HttpProcessorBuilder.create()
            // Use standard client-side protocol interceptors
            .add(new RequestContent()).add(new RequestTargetHost()).add(new RequestConnControl())
            .add(new RequestUserAgent("Test/1.1")).add(new RequestExpectContinue(true)).build();
    // Create client-side HTTP protocol handler
    HttpAsyncRequestExecutor protocolHandler = new HttpAsyncRequestExecutor();
    // Create client-side I/O event dispatch
    final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler,
            ConnectionConfig.DEFAULT);/* ww w  .  j  a v a  2  s .  co  m*/
    // Create client-side I/O reactor
    final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
    // Create HTTP connection pool
    BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, ConnectionConfig.DEFAULT);
    // Limit total number of connections to just two
    pool.setDefaultMaxPerRoute(2);
    pool.setMaxTotal(2);
    // Run the I/O reactor in a separate thread
    Thread t = new Thread(new Runnable() {

        public void run() {
            try {
                // Ready to go!
                ioReactor.execute(ioEventDispatch);
            } catch (InterruptedIOException ex) {
                System.err.println("Interrupted");
            } catch (IOException e) {
                System.err.println("I/O error: " + e.getMessage());
            }
            System.out.println("Shutdown");
        }

    });
    // Start the client thread
    t.start();
    // Create HTTP requester
    HttpAsyncRequester requester = new HttpAsyncRequester(httpproc);
    // Execute HTTP GETs to the following hosts and
    HttpHost[] targets = new HttpHost[] { new HttpHost("www.apache.org", 80, "http"),
            new HttpHost("www.verisign.com", 443, "https"), new HttpHost("www.google.com", 80, "http") };
    final CountDownLatch latch = new CountDownLatch(targets.length);
    for (final HttpHost target : targets) {
        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
        HttpCoreContext coreContext = HttpCoreContext.create();
        requester.execute(new BasicAsyncRequestProducer(target, request), new BasicAsyncResponseConsumer(),
                pool, coreContext,
                // Handle HTTP response from a callback
                new FutureCallback<HttpResponse>() {

                    public void completed(final HttpResponse response) {
                        latch.countDown();
                        System.out.println(target + "->" + response.getStatusLine());
                    }

                    public void failed(final Exception ex) {
                        latch.countDown();
                        System.out.println(target + "->" + ex);
                    }

                    public void cancelled() {
                        latch.countDown();
                        System.out.println(target + " cancelled");
                    }

                });
    }
    latch.await();
    System.out.println("Shutting down I/O reactor");
    ioReactor.shutdown();
    System.out.println("Done");

}

From source file:framework.httpclient.nio.NHttpClient.java

public static void main(String[] args) throws Exception {
    // Create HTTP protocol processing chain
    HttpProcessor httpproc = HttpProcessorBuilder.create()
            // Use standard client-side protocol interceptors
            .add(new RequestContent()).add(new RequestTargetHost()).add(new RequestConnControl())
            .add(new RequestUserAgent("LinkedHashSetVsTreeSet/1.1")).add(new RequestExpectContinue(true))
            .build();/*from w  w  w.  j  av  a  2 s.  c o  m*/

    // Create client-side HTTP protocol handler
    HttpAsyncRequestExecutor protocolHandler = new HttpAsyncRequestExecutor();

    // Create client-side I/O event dispatch
    //   IO 
    final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler,
            ConnectionConfig.DEFAULT);

    // Create client-side I/O reactor
    //   IO reactor
    final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();

    // Create HTTP connection pool
    //  HTTP 
    BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, ConnectionConfig.DEFAULT);

    // Limit total number of connections to just two
    pool.setDefaultMaxPerRoute(2);
    pool.setMaxTotal(2);

    // Run the I/O reactor in a separate thread
    Thread t = new Thread(new Runnable() {

        public void run() {
            try {
                // Ready to go!
                ioReactor.execute(ioEventDispatch);
            } catch (InterruptedIOException ex) {
                System.err.println("Interrupted");
            } catch (IOException e) {
                System.err.println("I/O error: " + e.getMessage());
            }
            System.out.println("Shutdown");
        }

    });
    // Start the client thread
    t.start();

    // Create HTTP requester
    //  HTTP 
    HttpAsyncRequester requester = new HttpAsyncRequester(httpproc);

    // Execute HTTP GETs to the following hosts and
    HttpHost[] targets = new HttpHost[] { new HttpHost("www.baidu.org", -1, "https"),
            //            new HttpHost("www.zhihu.com", -1, "https"),
            new HttpHost("www.bilibili.com", -1, "https") };

    final CountDownLatch latch = new CountDownLatch(targets.length);

    for (final HttpHost target : targets) {
        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
        HttpCoreContext coreContext = HttpCoreContext.create();
        requester.execute(new BasicAsyncRequestProducer(target, request), new BasicAsyncResponseConsumer(),
                pool, coreContext,
                // Handle HTTP response from a callback
                new FutureCallback<HttpResponse>() {

                    public void completed(final HttpResponse response) {
                        latch.countDown();
                        System.out.println(target + "->" + response.getStatusLine());
                    }

                    public void failed(final Exception ex) {
                        latch.countDown();
                        System.err.println(target + "->" + ex);
                        ex.printStackTrace();
                    }

                    public void cancelled() {
                        latch.countDown();
                        System.out.println(target + " cancelled");
                    }

                });
    }
    latch.await();
    System.out.println("Shutting down I/O reactor");
    ioReactor.shutdown();
    System.out.println("Done");
}

From source file:com.weibo.wesync.client.NHttpClient2.java

public static void main(String[] args) throws Exception {
    RSAPublicKey publicKey = RSAEncrypt.loadPublicKey("D:\\weibo\\meyou_gw\\conf\\public.pem");
    //  //from   www. j ava2 s. co  m
    byte[] cipher = RSAEncrypt.encrypt(publicKey, password.getBytes());
    password = RSAEncrypt.toHexString(cipher);

    // HTTP parameters for the client
    HttpParams params = new SyncBasicHttpParams();
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
            .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000)
            .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
            .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);

    // Create HTTP protocol processing chain
    HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
            // Use standard client-side protocol interceptors
            new RequestContent(), new RequestTargetHost(), new RequestConnControl(), new RequestUserAgent(),
            new RequestExpectContinue() });
    // Create client-side HTTP protocol handler
    HttpAsyncRequestExecutor protocolHandler = new HttpAsyncRequestExecutor();
    // Create client-side I/O event dispatch
    final IOEventDispatch ioEventDispatch = new DefaultHttpClientIODispatch(protocolHandler, params);
    // Create client-side I/O reactor
    IOReactorConfig config = new IOReactorConfig();
    config.setIoThreadCount(1);
    final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(config);
    // Create HTTP connection pool
    BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, params);
    // Limit total number of connections to just two
    pool.setDefaultMaxPerRoute(2);
    pool.setMaxTotal(1);

    // Run the I/O reactor in a separate thread
    Thread t = new Thread(new Runnable() {

        public void run() {
            try {
                // Ready to go!
                ioReactor.execute(ioEventDispatch);
            } catch (InterruptedIOException ex) {
                System.err.println("Interrupted");
            } catch (IOException e) {
                System.err.println("I/O error: " + e.getMessage());
            }
            System.out.println("Shutdown");
        }

    });
    // Start the client thread
    t.start();
    // Create HTTP requester
    //        HttpAsyncRequester requester = new HttpAsyncRequester(
    //                httpproc, new DefaultConnectionReuseStrategy(), params);
    // Execute HTTP GETs to the following hosts and
    HttpHost[] targets = new HttpHost[] {
            //              new HttpHost("123.125.106.28", 8093, "http"),
            //              new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            //                new HttpHost("123.125.106.28", 8093, "http"),
            new HttpHost("123.125.106.28", 8082, "http") };

    final CountDownLatch latch = new CountDownLatch(targets.length);
    int callbackId = 0;

    for (int i = 0; i < 1; i++) {
        for (final HttpHost target : targets) {
            BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", "/wesync");

            //              String usrpwd = Base64.encodeBase64String((username + ":" + password).getBytes());
            //              request.setHeader("authorization", "Basic " + usrpwd);
            request.setHeader("uid", "2565640713");
            Meyou.MeyouPacket packet = null;

            if (callbackId == 0) {
                packet = Meyou.MeyouPacket.newBuilder().setCallbackId(String.valueOf(callbackId++))
                        .setSort(MeyouSort.notice).build();
            } else {
                packet = Meyou.MeyouPacket.newBuilder().setCallbackId(String.valueOf(callbackId++))
                        .setSort(MeyouSort.wesync).build();
            }

            ByteArrayEntity entity = new ByteArrayEntity(packet.toByteArray());
            request.setEntity(entity);
            //           BasicHttpRequest request = new BasicHttpRequest("GET", "/test.html");

            System.out.println("send ...");
            HttpAsyncRequester requester = new HttpAsyncRequester(httpproc,
                    new DefaultConnectionReuseStrategy(), params);
            requester.execute(new BasicAsyncRequestProducer(target, request), new BasicAsyncResponseConsumer(),
                    pool, new BasicHttpContext(),
                    // Handle HTTP response from a callback
                    new FutureCallback<HttpResponse>() {
                        public void completed(final HttpResponse response) {
                            StatusLine status = response.getStatusLine();
                            int code = status.getStatusCode();

                            if (code == 200) {
                                try {
                                    latch.countDown();
                                    DataInputStream in;
                                    in = new DataInputStream(response.getEntity().getContent());
                                    int packetLength = in.readInt();
                                    int start = 0;

                                    while (packetLength > 0) {
                                        ByteArrayOutputStream outstream = new ByteArrayOutputStream(
                                                packetLength);
                                        byte[] buffer = new byte[1024];
                                        int len = 0;

                                        while (start < packetLength
                                                && (len = in.read(buffer, start, packetLength)) > 0) {
                                            outstream.write(buffer, 0, len);
                                            start += len;
                                        }

                                        Meyou.MeyouPacket packet0 = Meyou.MeyouPacket
                                                .parseFrom(outstream.toByteArray());
                                        System.out.println(target + "->" + packet0);

                                        if ((len = in.read(buffer, start, 4)) > 0) {
                                            packetLength = Util.readPacketLength(buffer);
                                        } else {
                                            break;
                                        }
                                    }
                                } catch (IllegalStateException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            } else {
                                System.out.println("error code=" + code + "|" + status.getReasonPhrase());
                            }
                        }

                        public void failed(final Exception ex) {
                            latch.countDown();
                            System.out.println(target + "->" + ex);
                        }

                        public void cancelled() {
                            latch.countDown();
                            System.out.println(target + " cancelled");
                        }

                    });

            Thread.sleep((long) (Math.random() * 10000));
        }
    }
    //        latch.await();
    //        System.out.println("Shutting down I/O reactor");
    //        ioReactor.shutdown();
    //        System.out.println("Done");
}

From source file:org.jenkinsci.plugins.relution_publisher.net.requests.ZeroCopyFileRequest.java

@Override
public Future<HttpResponse> execute(final HttpAsyncClient httpClient) throws FileNotFoundException {

    final HttpAsyncResponseConsumer<HttpResponse> consumer = new BasicAsyncResponseConsumer();
    final HttpAsyncRequestProducer producer = new ZeroCopyFileRequestProducer(this);

    return httpClient.execute(producer, consumer, null);
}

From source file:com.comcast.cns.io.HTTPEndpointAsyncPublisher.java

@Override
public void send() throws Exception {

    HttpAsyncRequester requester = new HttpAsyncRequester(httpProcessor, new DefaultConnectionReuseStrategy(),
            httpParams);/*from   w  w w  .  j  av  a 2s  . co  m*/
    final URL url = new URL(endpoint);
    final HttpHost target = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());

    BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
            url.getPath() + (url.getQuery() == null ? "" : "?" + url.getQuery()));
    composeHeader(request);

    String msg = null;

    if (message.getMessageStructure() == CNSMessageStructure.json) {
        msg = message.getProtocolSpecificMessage(CnsSubscriptionProtocol.http);
    } else {
        msg = message.getMessage();
    }

    if (!rawMessageDelivery && message.getMessageType() == CNSMessageType.Notification) {
        msg = com.comcast.cns.util.Util.generateMessageJson(message, CnsSubscriptionProtocol.http);
    }

    logger.debug("event=send_async_http_request endpoint=" + endpoint + "\" message=\"" + msg + "\"");

    request.setEntity(new NStringEntity(msg));

    requester.execute(new BasicAsyncRequestProducer(target, request), new BasicAsyncResponseConsumer(),
            connectionPool, new BasicHttpContext(), new FutureCallback<HttpResponse>() {

                public void completed(final HttpResponse response) {

                    int statusCode = response.getStatusLine().getStatusCode();

                    // accept all 2xx status codes

                    if (statusCode >= 200 && statusCode < 300) {
                        callback.onSuccess();
                    } else {
                        logger.warn(target + "://" + url.getPath() + "?" + url.getQuery() + " -> "
                                + response.getStatusLine());
                        callback.onFailure(statusCode);
                    }
                }

                public void failed(final Exception ex) {
                    logger.warn(target + " " + url.getPath() + " " + url.getQuery(), ex);
                    callback.onFailure(0);
                }

                public void cancelled() {
                    logger.warn(target + " " + url.getPath() + " " + url.getQuery() + " -> " + "cancelled");
                    callback.onFailure(1);
                }
            });
}

From source file:com.baidubce.http.BceHttpClient.java

/**
 * Executes the request and returns the result.
 *
 * @param request          The BCE request to send to the remote server
 * @param responseClass    A response handler to accept a successful response from the remote server
 * @param responseHandlers A response handler to accept an unsuccessful response from the remote server
 *
 * @throws com.baidubce.BceClientException  If any errors are encountered on the client while making the
 *             request or handling the response.
 * @throws com.baidubce.BceServiceException If any errors occurred in BCE while processing the request.
 *//*  ww w .j a v a 2  s . c  o m*/
public <T extends AbstractBceResponse> T execute(InternalRequest request, Class<T> responseClass,
        HttpResponseHandler[] responseHandlers) {
    // Apply whatever request options we know how to handle, such as user-agent.
    request.addHeader(Headers.USER_AGENT, this.config.getUserAgent());
    BceCredentials credentials = config.getCredentials();
    if (request.getCredentials() != null) {
        credentials = request.getCredentials();
    }
    long delayForNextRetryInMillis = 0;
    for (int attempt = 1;; ++attempt) {
        HttpRequestBase httpRequest = null;
        CloseableHttpResponse httpResponse = null;
        CloseableHttpAsyncClient httpAsyncClient = null;
        try {
            // Sign the request if credentials were provided
            if (credentials != null) {
                this.signer.sign(request, credentials);
            }

            requestLogger.debug("Sending Request: {}", request);

            httpRequest = this.createHttpRequest(request);

            HttpContext httpContext = this.createHttpContext(request);

            if (this.isHttpAsyncPutEnabled && httpRequest.getMethod().equals("PUT")) {
                httpAsyncClient = this.createHttpAsyncClient(this.createNHttpClientConnectionManager());
                httpAsyncClient.start();
                Future<HttpResponse> future = httpAsyncClient.execute(HttpAsyncMethods.create(httpRequest),
                        new BasicAsyncResponseConsumer(), httpContext, null);
                httpResponse = new BceCloseableHttpResponse(future.get());
            } else {
                httpResponse = this.httpClient.execute(httpRequest, httpContext);
            }
            HttpUtils.printRequest(httpRequest);
            BceHttpResponse bceHttpResponse = new BceHttpResponse(httpResponse);

            T response = responseClass.newInstance();
            for (HttpResponseHandler handler : responseHandlers) {
                if (handler.handle(bceHttpResponse, response)) {
                    break;
                }
            }

            // everything is ok
            return response;
        } catch (Exception e) {
            if (logger.isInfoEnabled()) {
                logger.info("Unable to execute HTTP request", e);
            }

            BceClientException bce;
            if (e instanceof BceClientException) {
                bce = (BceClientException) e;
            } else {
                bce = new BceClientException("Unable to execute HTTP request", e);
            }
            delayForNextRetryInMillis = this.getDelayBeforeNextRetryInMillis(httpRequest, bce, attempt,
                    this.config.getRetryPolicy());
            if (delayForNextRetryInMillis < 0) {
                throw bce;
            }

            logger.debug("Retriable error detected, will retry in {} ms, attempt number: {}",
                    delayForNextRetryInMillis, attempt);
            try {
                Thread.sleep(delayForNextRetryInMillis);
            } catch (InterruptedException e1) {
                throw new BceClientException("Delay interrupted", e1);
            }
            if (request.getContent() != null) {
                request.getContent().restart();
            }
            if (httpResponse != null) {
                try {
                    HttpEntity entity = httpResponse.getEntity();
                    if (entity != null && entity.isStreaming()) {
                        final InputStream instream = entity.getContent();
                        if (instream != null) {
                            instream.close();
                        }
                    }
                } catch (IOException e1) {
                    logger.debug("Fail to consume entity.", e1);
                    try {
                        httpResponse.close();
                    } catch (IOException e2) {
                        logger.debug("Fail to close connection.", e2);
                    }
                }
            }
        } finally {
            try {
                if (httpAsyncClient != null) {
                    httpAsyncClient.close();
                }
            } catch (IOException e) {
                logger.debug("Fail to close HttpAsyncClient", e);
            }
        }
    }
}

From source file:com.googlecode.jsonrpc4j.JsonRpcHttpAsyncClient.java

/**
 * Invokes the given method with the given arguments and invokes the
 * {@code JsonRpcCallback} with the result cast to the given
 * {@code returnType}, or null if void. The {@code extraHeaders} are added
 * to the request./*from   w ww  . j  a v a 2s.  co  m*/
 * 
 * @param methodName
 *            the name of the method to invoke
 * @param arguments
 *            the arguments to the method
 * @param extraHeaders
 *            extra headers to add to the request
 * @param returnType
 *            the return type
 * @param callback
 *            the {@code JsonRpcCallback}
 */
@SuppressWarnings("unchecked")
private <T> Future<T> doInvoke(String methodName, Object argument, Class<T> returnType,
        Map<String, String> extraHeaders, JsonRpcCallback<T> callback) {

    String path = serviceUrl.getPath() + (serviceUrl.getQuery() != null ? "?" + serviceUrl.getQuery() : "");
    int port = serviceUrl.getPort() != -1 ? serviceUrl.getPort() : serviceUrl.getDefaultPort();

    // create the HttpRequest
    HttpRequest request = new BasicHttpEntityEnclosingRequest("POST", path);

    addHeaders(request, headers);
    addHeaders(request, extraHeaders);

    // create the JSON payload
    try {
        writeRequest(methodName, argument, request);
    } catch (IOException e) {
        callback.onError(e);
    }

    HttpHost target = new HttpHost(serviceUrl.getHost(), port, serviceUrl.getProtocol());
    BasicAsyncRequestProducer asyncRequestProducer = new BasicAsyncRequestProducer(target, request);
    BasicAsyncResponseConsumer asyncResponseConsumer = new BasicAsyncResponseConsumer();

    RequestAsyncFuture<T> futureCallback = new RequestAsyncFuture<T>(returnType, callback);

    BasicHttpContext httpContext = new BasicHttpContext();
    requester.execute(asyncRequestProducer, asyncResponseConsumer, pool, httpContext, futureCallback);

    return (callback instanceof JsonRpcFuture ? (Future<T>) callback : null);
}

From source file:org.apache.nifi.remote.util.SiteToSiteRestApiClient.java

/**
 * <p>/*from  w  w w . j a  va  2s .  c o m*/
 * Initiate a transaction for sending data.
 * </p>
 *
 * <p>
 * If a proxy server requires auth, the proxy server returns 407 response with available auth schema such as basic or digest.
 * Then client has to resend the same request with its credential added.
 * This mechanism is problematic for sending data from NiFi.
 * </p>
 *
 * <p>
 * In order to resend a POST request with auth param,
 * NiFi has to either read flow-file contents to send again, or keep the POST body somewhere.
 * If we store that in memory, it would causes OOM, or storing it on disk slows down performance.
 * Rolling back processing session would be overkill.
 * Reading flow-file contents only when it's ready to send in a streaming way is ideal.
 * </p>
 *
 * <p>
 * Additionally, the way proxy authentication is done is vary among Proxy server software.
 * Some requires 407 and resend cycle for every requests, while others keep a connection between a client and
 * the proxy server, then consecutive requests skip auth steps.
 * The problem is, that how should we behave is only told after sending a request to the proxy.
 * </p>
 *
 * In order to handle above concerns correctly and efficiently, this method do the followings:
 *
 * <ol>
 * <li>Send a GET request to controller resource, to initiate an HttpAsyncClient. The instance will be used for further requests.
 *      This is not required by the Site-to-Site protocol, but it can setup proxy auth state safely.</li>
 * <li>Send a POST request to initiate a transaction. While doing so, it captures how a proxy server works.
 * If 407 and resend cycle occurs here, it implies that we need to do the same thing again when we actually send the data.
 * Because if the proxy keeps using the same connection and doesn't require an auth step, it doesn't do so here.</li>
 * <li>Then this method stores whether the final POST request should wait for the auth step.
 * So that {@link #openConnectionForSend} can determine when to produce contents.</li>
 * </ol>
 *
 * <p>
 * The above special sequence is only executed when a proxy instance is set, and its username is set.
 * </p>
 *
 * @param post a POST request to establish transaction
 * @return POST request response
 * @throws IOException thrown if the post request failed
 */
private HttpResponse initiateTransactionForSend(final HttpPost post) throws IOException {
    if (shouldCheckProxyAuth()) {
        final CloseableHttpAsyncClient asyncClient = getHttpAsyncClient();
        final HttpGet get = createGetControllerRequest();
        final Future<HttpResponse> getResult = asyncClient.execute(get, null);
        try {
            final HttpResponse getResponse = getResult.get(readTimeoutMillis, TimeUnit.MILLISECONDS);
            logger.debug("Proxy auth check has done. getResponse={}", getResponse.getStatusLine());
        } catch (final ExecutionException e) {
            logger.debug("Something has happened at get controller requesting thread for proxy auth check. {}",
                    e.getMessage());
            throw toIOException(e);
        } catch (TimeoutException | InterruptedException e) {
            throw new IOException(e);
        }
    }

    final HttpAsyncRequestProducer asyncRequestProducer = new HttpAsyncRequestProducer() {
        private boolean requestHasBeenReset = false;

        @Override
        public HttpHost getTarget() {
            return URIUtils.extractHost(post.getURI());
        }

        @Override
        public HttpRequest generateRequest() throws IOException, HttpException {
            final BasicHttpEntity entity = new BasicHttpEntity();
            post.setEntity(entity);
            return post;
        }

        @Override
        public void produceContent(ContentEncoder encoder, IOControl ioctrl) throws IOException {
            encoder.complete();
            if (shouldCheckProxyAuth() && requestHasBeenReset) {
                logger.debug("Produced content again, assuming the proxy server requires authentication.");
                proxyAuthRequiresResend.set(true);
            }
        }

        @Override
        public void requestCompleted(HttpContext context) {
            debugProxyAuthState(context);
        }

        @Override
        public void failed(Exception ex) {
            final String msg = String.format("Failed to create transaction for %s", post.getURI());
            logger.error(msg, ex);
            eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, msg);
        }

        @Override
        public boolean isRepeatable() {
            return true;
        }

        @Override
        public void resetRequest() throws IOException {
            requestHasBeenReset = true;
        }

        @Override
        public void close() throws IOException {
        }
    };

    final Future<HttpResponse> responseFuture = getHttpAsyncClient().execute(asyncRequestProducer,
            new BasicAsyncResponseConsumer(), null);
    final HttpResponse response;
    try {
        response = responseFuture.get(readTimeoutMillis, TimeUnit.MILLISECONDS);

    } catch (final ExecutionException e) {
        logger.debug("Something has happened at initiate transaction requesting thread. {}", e.getMessage());
        throw toIOException(e);
    } catch (TimeoutException | InterruptedException e) {
        throw new IOException(e);
    }
    return response;
}

From source file:org.apache.nifi.remote.util.SiteToSiteRestApiClient.java

public void openConnectionForSend(final String transactionUrl, final Peer peer) throws IOException {

    final CommunicationsSession commSession = peer.getCommunicationsSession();
    final String flowFilesPath = transactionUrl + "/flow-files";
    final HttpPost post = createPost(flowFilesPath);
    // Set uri so that it'll be used as transit uri.
    ((HttpCommunicationsSession) peer.getCommunicationsSession()).setDataTransferUrl(post.getURI().toString());

    post.setHeader("Content-Type", "application/octet-stream");
    post.setHeader("Accept", "text/plain");
    post.setHeader(HttpHeaders.PROTOCOL_VERSION,
            String.valueOf(transportProtocolVersionNegotiator.getVersion()));

    setHandshakeProperties(post);//from   ww  w .  j a v a  2  s  .c  o  m

    final CountDownLatch initConnectionLatch = new CountDownLatch(1);

    final URI requestUri = post.getURI();
    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream = new PipedInputStream(outputStream,
            DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);
    final ReadableByteChannel dataPacketChannel = Channels.newChannel(inputStream);
    final HttpAsyncRequestProducer asyncRequestProducer = new HttpAsyncRequestProducer() {

        private final ByteBuffer buffer = ByteBuffer.allocate(DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);

        private int totalRead = 0;
        private int totalProduced = 0;

        private boolean requestHasBeenReset = false;

        @Override
        public HttpHost getTarget() {
            return URIUtils.extractHost(requestUri);
        }

        @Override
        public HttpRequest generateRequest() throws IOException, HttpException {

            // Pass the output stream so that Site-to-Site client thread can send
            // data packet through this connection.
            logger.debug("sending data to {} has started...", flowFilesPath);
            ((HttpOutput) commSession.getOutput()).setOutputStream(outputStream);
            initConnectionLatch.countDown();

            final BasicHttpEntity entity = new BasicHttpEntity();
            entity.setChunked(true);
            entity.setContentType("application/octet-stream");
            post.setEntity(entity);
            return post;
        }

        private final AtomicBoolean bufferHasRemainingData = new AtomicBoolean(false);

        /**
         * If the proxy server requires authentication, the same POST request has to be sent again.
         * The first request will result 407, then the next one will be sent with auth headers and actual data.
         * This method produces a content only when it's need to be sent, to avoid producing the flow-file contents twice.
         * Whether we need to wait auth is determined heuristically by the previous POST request which creates transaction.
         * See {@link SiteToSiteRestApiClient#initiateTransactionForSend(HttpPost)} for further detail.
         */
        @Override
        public void produceContent(final ContentEncoder encoder, final IOControl ioControl) throws IOException {

            if (shouldCheckProxyAuth() && proxyAuthRequiresResend.get() && !requestHasBeenReset) {
                logger.debug("Need authentication with proxy server. Postpone producing content.");
                encoder.complete();
                return;
            }

            if (bufferHasRemainingData.get()) {
                // If there's remaining buffer last time, send it first.
                writeBuffer(encoder);
                if (bufferHasRemainingData.get()) {
                    return;
                }
            }

            int read;
            // This read() blocks until data becomes available,
            // or corresponding outputStream is closed.
            if ((read = dataPacketChannel.read(buffer)) > -1) {

                logger.trace("Read {} bytes from dataPacketChannel. {}", read, flowFilesPath);
                totalRead += read;

                buffer.flip();
                writeBuffer(encoder);

            } else {

                final long totalWritten = commSession.getOutput().getBytesWritten();
                logger.debug(
                        "sending data to {} has reached to its end. produced {} bytes by reading {} bytes from channel. {} bytes written in this transaction.",
                        flowFilesPath, totalProduced, totalRead, totalWritten);

                if (totalRead != totalWritten || totalProduced != totalWritten) {
                    final String msg = "Sending data to %s has reached to its end, but produced : read : wrote byte sizes (%d : %d : %d) were not equal. Something went wrong.";
                    throw new RuntimeException(
                            String.format(msg, flowFilesPath, totalProduced, totalRead, totalWritten));
                }
                transferDataLatch.countDown();
                encoder.complete();
                dataPacketChannel.close();
            }

        }

        private void writeBuffer(ContentEncoder encoder) throws IOException {
            while (buffer.hasRemaining()) {
                final int written = encoder.write(buffer);
                logger.trace("written {} bytes to encoder.", written);
                if (written == 0) {
                    logger.trace("Buffer still has remaining. {}", buffer);
                    bufferHasRemainingData.set(true);
                    return;
                }
                totalProduced += written;
            }
            bufferHasRemainingData.set(false);
            buffer.clear();
        }

        @Override
        public void requestCompleted(final HttpContext context) {
            logger.debug("Sending data to {} completed.", flowFilesPath);
            debugProxyAuthState(context);
        }

        @Override
        public void failed(final Exception ex) {
            final String msg = String.format("Failed to send data to %s due to %s", flowFilesPath,
                    ex.toString());
            logger.error(msg, ex);
            eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, msg);
        }

        @Override
        public boolean isRepeatable() {
            // In order to pass authentication, request has to be repeatable.
            return true;
        }

        @Override
        public void resetRequest() throws IOException {
            logger.debug("Sending data request to {} has been reset...", flowFilesPath);
            requestHasBeenReset = true;
        }

        @Override
        public void close() throws IOException {
            logger.debug("Closing sending data request to {}", flowFilesPath);
            closeSilently(outputStream);
            closeSilently(dataPacketChannel);
            stopExtendingTtl();
        }
    };

    postResult = getHttpAsyncClient().execute(asyncRequestProducer, new BasicAsyncResponseConsumer(), null);

    try {
        // Need to wait the post request actually started so that we can write to its output stream.
        if (!initConnectionLatch.await(connectTimeoutMillis, TimeUnit.MILLISECONDS)) {
            throw new IOException("Awaiting initConnectionLatch has been timeout.");
        }

        // Started.
        transferDataLatch = new CountDownLatch(1);
        startExtendingTtl(transactionUrl, dataPacketChannel, null);

    } catch (final InterruptedException e) {
        throw new IOException("Awaiting initConnectionLatch has been interrupted.", e);
    }

}