Add new interfaces (PreInvocationInterceptor, PostInvocationInterceptor, and InvocationBuilderListener) documentation (#4411)

* Add new PreInvocationInterceptor, PostInvocationInterceptor, and InvocationBuilderListener interfaces documentation

Signed-off-by: tvallin <thibault.vallin@oracle.com>
diff --git a/docs/src/main/docbook/client.xml b/docs/src/main/docbook/client.xml
index 90964a3..e0b01cb 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -999,4 +999,135 @@
 
 
     </section>
+
+    <section>
+        <title>InvocationInterceptors</title>
+        <para>
+            Suppose a case that the start of the request is to be logged and even measured.
+            This can be done by <literal>ClientRequestFilter</literal>, which is usually invoked before the request is wired on the network.
+            However, the filter may be called as a last of the filters in the chain. Sure, it can have the highest priority,
+            but the other filters can have the very same priority! Some long-running operations can be performed before the
+            measuring can actually start. Even worse, the filter may even be skipped from the chain by the previous
+            <literal>#abortWith</literal>!
+        </para>
+        <section>
+            <title>PreInvocationInterceptor</title>
+            <para>
+                For this, <literal>PreInvocationInterceptor</literal>, the code that executes before the <literal>ClientRequestFilters</literal>
+                are invoked, has been added to the client request chain. Jersey ensures all the interceptors are invoked with each request.
+                The interceptor contains a single <literal>#beforeRequest</literal> method, which corresponds to <literal>ClientRequestFilter</literal>:
+            </para>
+            <programlisting language="java">
+                /**
+                * The method invoked before the request starts.
+                * @param requestContext the request context shared with
+                * ClientRequestFilter.
+                */
+                void beforeRequest(ClientRequestContext requestContext);
+            </programlisting>
+            <para>
+                Note that only a single <literal>#abortWith</literal> is allowed in all <literal>PreInvocationInterceptors</literal>,
+                otherwise an <literal>IllegalStateException</literal> is thrown.
+                All the exceptions accumulated in <literal>PreInvocationInterceptors</literal> are thrown in a single Exception,
+                available through <literal>#getSuppressed()</literal>.
+            </para>
+        </section>
+        <section>
+            <title>PostInvocationInterceptor</title>
+            <para>
+                Similarly, <literal>ClientResponseFilter</literal> seems to be a good place where the total time of the HTTP request can be measured,
+                but similarly to <literal>ClientRequestFilter</literal>, the response filter may not be invoked at all.
+                For this, <literal>PostInvocationInterceptor</literal> has been introduced. Jersey runtime ensures that every
+                <literal>PostInvocationInterceptor</literal> is called. Since an exception can occur during the HTTP request,
+                <literal>PostInvocationInterceptor</literal> comes with two methods:
+            </para>
+            <programlisting language="java">
+                /**
+                * The method is invoked after a request when no
+                * is thrown, or the Throwables are resolved
+                * by previous PostInvocationInterceptor.
+                *
+                * @param requestContext the request context.
+                * @param responseContext the response context
+                * of the original Response or response context
+                * defined by the new resolving Response.
+                */
+                void afterRequest(ClientRequestContext requestContext, ClientResponseContext responseContext);
+
+                /**
+                * The method is invoked after a Throwable is caught
+                * during the client request chain processing.
+                *
+                * @param requestContext the request context.
+                * @param exceptionContext the context available to handle the
+                * caught Throwables.
+                */
+                void onException(ClientRequestContext requestContext, ExceptionContext exceptionContext);
+            </programlisting>
+            <para>
+                The <literal>#afterRequest</literal> method is executed when no exception has been thrown during the HTTP request,
+                <literal>#onException</literal> method is executed if the exception has been thrown during the request.
+                It is possible to set a response in <literal>#onException</literal>, and the consecutive <literal>PostInvocationInterceptor</literal> will
+                execute its <literal>#afterRequest</literal> method.
+
+                The measuring example can looks as follows, then:
+            </para>
+            <programlisting language="java" linenumbering="numbered">
+                String response = ClientBuilder.newClient().target("path")
+                    .register(new PreInvocationInterceptor() {
+                        @Override
+                        public void beforeRequest(ClientRequestContext requestContext) {
+                            startTime = System.currentTimeMillis();
+                        }
+                    })
+                    .register(new PostInvocationInterceptor() {
+                        @Override
+                        public void afterRequest(ClientRequestContext requestContext, ClientResponseContext responseContext) {
+                            logDuration(System.currentTimeMillis() - startTime);
+                        }
+                        @Override
+                        public void onException(ClientRequestContext requestContext, ExceptionContext exceptionContext) {
+                            logDuration(System.currentTimeMillis() - startTime);
+                        }
+                    })
+                    .request().get().readEntity(String.class);
+            </programlisting>
+        </section>
+    </section>
+    <section>
+        <title>InvocationBuilderListener</title>
+        <para>
+            InvocationBuilderListener is an interface that is inspired by Microprofile REST Client <literal>RestClientBuilderListener</literal>
+            and it contains a single method:
+        </para>
+        <programlisting language="java">
+            /**
+            * Whenever an Invocation.Builder is created, (i.e. when
+            * WebTarget#request() is called, this method would be invoked.
+            *
+            * @param context the updated InvocationBuilderContext.
+            */
+            void onNewBuilder(InvocationBuilderContext context);
+        </programlisting>
+        <para>
+            <literal>InvocationBuilderContext</literal> a subset of methods of the <literal>Invocation.Builder</literal>. It can be used to call the default
+            values of the <literal>Invocation.Builder</literal>. Since it is invoked at the time <literal>Invocation.Builder</literal> is instantiated, any consequent
+            calls of the <literal>Invocation.Builder</literal>‘s methods will replace the defaults set by the <literal>InvocationBuilderListener</literal>.
+
+            For instance, if all the HTTP requests should contain a custom HTTP header,
+            there can be created a feature that would be registered on the client:
+        </para>
+        <programlisting language="java" linenumbering="numbered">
+            public static class MyFeature implements Feature {
+                @Override
+                public boolean configure(FeatureContext context) {
+                    context.register(
+                        (InvocationBuilderListener)(l)-&gt;
+                        l.getHeaders().add("MY_HEADER", "MY_VALUE")
+                    );
+                    return true;
+                }
+            }
+        </programlisting>
+    </section>
 </chapter>