<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
                 "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<!-- 
    ====================================================================
    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.
    ====================================================================
-->
<chapter id="advanced">
    <title>Advanced topics</title>
    <section>
        <title>Custom client connections</title>
        <para>In certain situations it may be necessary to customize the way HTTP messages get
            transmitted across the wire beyond what is possible using HTTP parameters in
            order to be able to deal non-standard, non-compliant behaviours. For instance, for web
            crawlers it may be necessary to force HttpClient into accepting malformed response heads
            in order to salvage the content of the messages. </para>
        <para>Usually the process of plugging in a custom message parser or a custom connection
            implementation involves several steps:</para>
        <itemizedlist>
            <listitem>
                <para>Provide a custom <interfacename>LineParser</interfacename> /
                        <interfacename>LineFormatter</interfacename> interface implementation.
                    Implement message parsing / formatting logic as required.</para>
                <programlisting><![CDATA[
class MyLineParser extends BasicLineParser {

    @Override
    public Header parseHeader(
            CharArrayBuffer buffer) throws ParseException {
        try {
            return super.parseHeader(buffer);
        } catch (ParseException ex) {
            // Suppress ParseException exception
            return new BasicHeader(buffer.toString(), null);
        }
    }

}
]]></programlisting>
            </listitem>
            <listitem>
                <para>Provide a custom <interfacename>HttpConnectionFactory</interfacename>
                    implementation. Replace default request writer and / or response parser
                    with custom ones as required. </para>
                <programlisting><![CDATA[
HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory =
        new ManagedHttpClientConnectionFactory(
            new DefaultHttpRequestWriterFactory(),
            new DefaultHttpResponseParserFactory(
                    new MyLineParser(), new DefaultHttpResponseFactory()));
]]></programlisting>
            </listitem>
            <listitem>
                <para>Configure HttpClient to use the custom connection factory.</para>
                <programlisting><![CDATA[
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
    connFactory);
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();
]]></programlisting>
            </listitem>
        </itemizedlist>
    </section>
    <section id="stateful_conn">
        <title>Stateful HTTP connections</title>
        <para>While HTTP specification assumes that session state information is always embedded in
            HTTP messages in the form of HTTP cookies and therefore HTTP connections are always
            stateless, this assumption does not always hold true in real life. There are cases when
            HTTP connections are created with a particular user identity or within a particular
            security context and therefore cannot be shared with other users and can be reused by
            the same user only. Examples of such stateful HTTP connections are
                <literal>NTLM</literal> authenticated connections and SSL connections with client
            certificate authentication.</para>
        <section>
            <title>User token handler</title>
            <para>HttpClient relies on <interfacename>UserTokenHandler</interfacename> interface to
                determine if the given execution context is user specific or not. The token object
                returned by this handler is expected to uniquely identify the current user if the
                context is user specific or to be null if the context does not contain any resources
                or details specific to the current user. The user token will be used to ensure that
                user specific resources will not be shared with or reused by other users.</para>
            <para>The default implementation of the <interfacename>UserTokenHandler</interfacename>
                interface uses an instance of Principal class to represent a state object for HTTP
                connections, if it can be obtained from the given execution context.
                    <classname>DefaultUserTokenHandler</classname> will use the user principle of
                connection based authentication schemes such as <literal>NTLM</literal> or that of
                the SSL session with client authentication turned on. If both are unavailable, null
                token will be returned.</para>
            <programlisting><![CDATA[
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context = HttpClientContext.create();
HttpGet httpget = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response = httpclient.execute(httpget, context);
try {
    Principal principal = context.getUserToken(Principal.class);
    System.out.println(principal);
} finally {
    response.close();
}
]]></programlisting>
            <para>Users can provide a custom implementation if the default one does not satisfy
                their needs:</para>
            <programlisting><![CDATA[
UserTokenHandler userTokenHandler = new UserTokenHandler() {

    public Object getUserToken(HttpContext context) {
        return context.getAttribute("my-token");
    }

};
CloseableHttpClient httpclient = HttpClients.custom()
        .setUserTokenHandler(userTokenHandler)
        .build();
]]></programlisting>
        </section>
        <section>
            <title>Persistent stateful connections</title>
            <para>Please note that a persistent connection that carries a state object can be reused
                only if the same state object is bound to the execution context when requests
                are executed. So, it is really important to ensure the either same context is
                reused for execution of subsequent HTTP requests by the same user or the user
                token is bound to the context prior to request execution.</para>
            <programlisting><![CDATA[
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpClientContext context1 = HttpClientContext.create();
HttpGet httpget1 = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response1 = httpclient.execute(httpget1, context1);
try {
    HttpEntity entity1 = response1.getEntity();
} finally {
    response1.close();
}
Principal principal = context1.getUserToken(Principal.class);

HttpClientContext context2 = HttpClientContext.create();
context2.setUserToken(principal);
HttpGet httpget2 = new HttpGet("http://localhost:8080/");
CloseableHttpResponse response2 = httpclient.execute(httpget2, context2);
try {
    HttpEntity entity2 = response2.getEntity();
} finally {
    response2.close();
}
]]></programlisting>
        </section>
    </section>
    <section>
        <title>Using the FutureRequestExecutionService</title>

        <para>Using the FutureRequestExecutionService, you can schedule http calls and treat the response
            as a Future. This is useful when e.g. making multiple calls to a web service. The advantage of using
            the FutureRequestExecutionService is that you can use multiple threads to schedule requests concurrently, set timeouts on
            the tasks, or cancel them when a response is no longer necessary.
        </para>

        <para>FutureRequestExecutionService wraps the request with a HttpRequestFutureTask, which extends FutureTask. This
        class allows you to cancel the task as well as keep track of various metrics such as request duration.</para>

        <section>
            <title>Creating the FutureRequestExecutionService</title>
            <para>The constructor for the futureRequestExecutionService takes any existing httpClient instance and an ExecutorService
            instance. When configuring both, it is important to align the maximum number of connections with the number of threads
            you are going to use. When there are more threads than connections, the connections may start timing out because there are no
            available connections. When there are more connections than threads, the futureRequestExecutionService will not use all of them</para>

            <programlisting><![CDATA[
HttpClient httpClient = HttpClientBuilder.create().setMaxConnPerRoute(5).build();
ExecutorService executorService = Executors.newFixedThreadPool(5);
FutureRequestExecutionService futureRequestExecutionService =
    new FutureRequestExecutionService(httpClient, executorService);
]]></programlisting>
        </section>

        <section>
            <title>Scheduling requests</title>
            <para>To schedule a request, simply provide a HttpUriRequest, HttpContext, and a ResponseHandler. Because
                the request is processed by the executor service, a ResponseHandler is mandatory.</para>

            <programlisting><![CDATA[
private final class OkidokiHandler implements ResponseHandler<Boolean> {
    public Boolean handleResponse(
            final HttpResponse response) throws ClientProtocolException, IOException {
        return response.getStatusLine().getStatusCode() == 200;
    }
}

HttpRequestFutureTask<Boolean> task = futureRequestExecutionService.execute(
    new HttpGet("http://www.google.com"), HttpClientContext.create(),
    new OkidokiHandler());
// blocks until the request complete and then returns true if you can connect to Google
boolean ok=task.get();
]]></programlisting>
        </section>
        <section>
            <title>Canceling tasks</title>
            <para>Scheduled tasks may be cancelled. If the task is not yet executing but merely queued for execution, it simply will never execute. If it is executing and the mayInterruptIfRunning parameter is set to true, abort() will be called on the request; otherwise the response will simply be ignored but the request will be allowed to complete normally. Any subsequent calls to task.get() will fail with an IllegalStateException. It should be noticed that canceling tasks merely frees up the client side resources. The request may actually be handled normally on the server side. </para>
            <programlisting><![CDATA[
task.cancel(true)
task.get() // throws an Exception
]]></programlisting>
        </section>
        <section>
            <title>Callbacks</title>
            <para>Instead of manually calling task.get(), you can also use a FutureCallback instance that gets callbacks when the request completes. This is the
                same interface as is used in HttpAsyncClient</para>
                <programlisting><![CDATA[

private final class MyCallback implements FutureCallback<Boolean> {

    public void failed(final Exception ex) {
        // do something
    }

    public void completed(final Boolean result) {
        // do something
    }

    public void cancelled() {
        // do something
    }
}

HttpRequestFutureTask<Boolean> task = futureRequestExecutionService.execute(
    new HttpGet("http://www.google.com"), HttpClientContext.create(),
    new OkidokiHandler(), new MyCallback());
]]></programlisting>
        </section>
        <section>
            <title>Metrics</title>
            <para>FutureRequestExecutionService is typically used in applications that make large amounts of
                web service calls. To facilitate e.g. monitoring or configuration tuning, the FutureRequestExecutionService keeps
                track of several metrics.</para>
            <para>Each HttpRequestFutureTask provides methods to get the time the task was scheduled,
                started, and ended. Additionally, request and task duration are available as well. These
                metrics are aggregated in the FutureRequestExecutionService in a FutureRequestExecutionMetrics
                instance that may be accessed through FutureRequestExecutionService.metrics().</para>
            <programlisting><![CDATA[
task.scheduledTime() // returns the timestamp the task was scheduled
task.startedTime() // returns the timestamp when the task was started
task.endedTime() // returns the timestamp when the task was done executing
task.requestDuration // returns the duration of the http request
task.taskDuration // returns the duration of the task from the moment it was scheduled

FutureRequestExecutionMetrics metrics = futureRequestExecutionService.metrics()
metrics.getActiveConnectionCount() // currently active connections
metrics.getScheduledConnectionCount(); // currently scheduled connections
metrics.getSuccessfulConnectionCount(); // total number of successful requests
metrics.getSuccessfulConnectionAverageDuration(); // average request duration
metrics.getFailedConnectionCount(); // total number of failed tasks
metrics.getFailedConnectionAverageDuration(); // average duration of failed tasks
metrics.getTaskCount(); // total number of tasks scheduled
metrics.getRequestCount(); // total number of requests
metrics.getRequestAverageDuration(); // average request duration
metrics.getTaskAverageDuration(); // average task duration
]]></programlisting>
        </section>
    </section>
</chapter>
