~~ ====================================================================
~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements.  See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership.  The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License.  You may obtain a copy of the License at
~~ 
~~   http://www.apache.org/licenses/LICENSE-2.0
~~ 
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied.  See the License for the
~~ specific language governing permissions and limitations
~~ under the License.
~~ ====================================================================
~~ 
~~ This software consists of voluntary contributions made by many
~~ individuals on behalf of the Apache Software Foundation.  For more
~~ information on the Apache Software Foundation, please see
~~ <http://www.apache.org/>.

    ----------
    HttpAsyncClient Quick Start
    ----------
    ----------
    ----------

HttpAsyncClient Quick Start

    [[1]] Download 'Binary' package of the latest HttpAsyncClient 4.1 release or configure
    dependency on {{{./httpasyncclient/dependency-info.html}HttpAsyncClient}} module using 
    a dependency manager of your choice as described {{{./download.html}here}}. 

    [[1]] HttpAsyncClient 4.1 requires Java 1.6 or newer. 

    [[1]] The code fragment below illustrates the most fundamental aspects of asynchronous
    request execution with HttpAsyncClient.

-------------    
CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
try {
    // Start the client
    httpclient.start();

    // Execute request
    final HttpGet request1 = new HttpGet("http://www.apache.org/");
    Future<HttpResponse> future = httpclient.execute(request1, null);
    // and wait until a response is received
    HttpResponse response1 = future.get();
    System.out.println(request1.getRequestLine() + "->" + response1.getStatusLine());

    // One most likely would want to use a callback for operation result
    final CountDownLatch latch1 = new CountDownLatch(1);
    final HttpGet request2 = new HttpGet("http://www.apache.org/");
    httpclient.execute(request2, new FutureCallback<HttpResponse>() {

        public void completed(final HttpResponse response2) {
            latch1.countDown();
            System.out.println(request2.getRequestLine() + "->" + response2.getStatusLine());
        }

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

        public void cancelled() {
            latch1.countDown();
            System.out.println(request2.getRequestLine() + " cancelled");
        }

    });
    latch1.await();

    // In real world one most likely would also want to stream
    // request and response body content
    final CountDownLatch latch2 = new CountDownLatch(1);
    final HttpGet request3 = new HttpGet("http://www.apache.org/");
    HttpAsyncRequestProducer producer3 = HttpAsyncMethods.create(request3);
    AsyncCharConsumer<HttpResponse> consumer3 = new AsyncCharConsumer<HttpResponse>() {

        HttpResponse response;

        @Override
        protected void onResponseReceived(final HttpResponse response) {
            this.response = response;
        }

        @Override
        protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
            // Do something useful
        }

        @Override
        protected void releaseResources() {
        }

        @Override
        protected HttpResponse buildResult(final HttpContext context) {
            return this.response;
        }

    };
    httpclient.execute(producer3, consumer3, new FutureCallback<HttpResponse>() {

        public void completed(final HttpResponse response3) {
            latch2.countDown();
            System.out.println(request3.getRequestLine() + "->" + response3.getStatusLine());
        }

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

        public void cancelled() {
            latch2.countDown();
            System.out.println(request3.getRequestLine() + " cancelled");
        }

    });
    latch2.await();

} finally {
    httpclient.close();
}
-------------    

    [[1]] Take a look at the {{{../httpcomponents-core-ga/tutorial/html/index.html}HttpCore 
    tutorial}} for introduction to fundamentals of asynchronous HTTP communication with
    HttpComponents.
    
    [[1]] Another good way of getting started with HttpAsyncClient is by seeing it in action. Take 
    a look at the samples shipped with the release package or available {{{./examples.html}online}}.
    

