<?xml version="1.0"?>
<!--

    Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.

    This program and the accompanying materials are made available under the
    terms of the Eclipse Public License v. 2.0, which is available at
    http://www.eclipse.org/legal/epl-2.0.

    This Source Code may also be made available under the following Secondary
    Licenses when the conditions for such availability set forth in the
    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
    version 2 with the GNU Classpath Exception, which is available at
    https://www.gnu.org/software/classpath/license.html.

    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

-->

<!DOCTYPE chapter [
        <!ENTITY % ents SYSTEM "jersey.ent" > %ents;
        <!ENTITY jersey.github.rx.example.link "<link xlink:href='&jersey.github.examples.uri;/rx-client-webapp'>Travel Agency (Orchestration Layer) Example using Reactive Jersey Client API</link>">
        <!ENTITY jersey.github.rx.java8.example.link "<link xlink:href='&jersey.github.examples.uri;/rx-client-java8-webapp'>Travel Agency (Orchestration Layer) Example using Reactive Jersey Client API (Java 8)</link>">
]>

<chapter xmlns="http://docbook.org/ns/docbook"
         version="5.0"
         xml:lang="en"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd
                             http://www.w3.org/1999/xlink http://www.w3.org/1999/xlink.xsd"
         xml:id="rx-client">

    <title>Reactive JAX-RS Client API</title>

    <warning>
        <para>
            Jersey 2.26 (JAX-RS 2.1 implementation) dropped Jersey-proprietary API in favor of JAX-RS 2.1 Reactive Client API.
            For Jersey 3.x this approach is still valid.
        </para>
    </warning>

    <para>
        Reactive client extension is quite a generic API allowing end users to utilize the popular reactive programming model
        when using JAX-RS Client. The API is designed to be extensible, so any existing reactive framework can integrate with
        it and there is build in support for CompletionStage. Along with describing the API itself, this section also covers
        existing extension modules and provides hints to implement a custom extension if needed.
    </para>

    <para>
        If you are not familiar with the JAX-RS Client API, it is recommended that you see <xref linkend="client"/>
        where the basics of JAX-RS Client API along with some advanced techniques are described.
    </para>



    <section>
        <title>Motivation for Reactive Client Extension</title>

        <simplesect>
            <title>The Problem</title>

            <para>
                Imagine a travel agency whose information system consists of multiple basic services. These services might be built
                using different technologies (JMS, EJB, WS, ...). For simplicity we presume that the services can be
                consumed using REST interface via HTTP method calls (e.g. using a JAX-RS Client). We also presume that the basic
                services we need to work with are:

                <itemizedlist>
                    <listitem>
                        <para>
                            <emphasis>Customers service</emphasis> – provides information about customers of the travel agency.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis>Destinations service</emphasis> – provides a list of visited and recommended destinations
                            for an authenticated customer.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis>Weather service</emphasis> – provides weather forecast for a given destination.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis>Quoting service</emphasis> – provides price calculation for a customer to travel to
                            a recommended destination.
                        </para>
                    </listitem>
                </itemizedlist>
            </para>
            <para>
                The task is to create a publicly available feature that would, for an authenticated user, display a list of 10 last visited places and
                also display a list of 10 new recommended destinations including weather forecast and price calculations for the
                user. Notice that some of the requests (to retrieve data) depend on results of previous requests. E.g. getting
                recommended destinations depends on obtaining information about the authenticated user first. Obtaining weather
                forecast depends on destination information, etc. This relationship between some of the requests is an important part of the
                problem and an area where you can take a real advantage of the reactive programming model.
            </para>
            <para>
                One way how to obtain data is to make multiple HTTP method calls from the client (e.g. mobile device) to all
                services involved and combine the retrieved data on the client. However, since the basic services are available
                in the internal network only we'd rather create a public orchestration layer instead of exposing all internal services to the outside world.
                The orchestration layer would expose only the desired operations of the basic services
                to the public. To limit traffic and achieve lower latency we'd like to return all the necessary
                information to the client in a single response.
            </para>
            <para>
                The orchestration layer is illustrated in the <xref linkend="rx.client.motivation.problem" xrefstyle="select: label" />.
                The layer accepts requests from the outside and is responsible of invoking multiple requests to the internal services.
                When responses from the internal services are available in the orchestration layer they're combined into
                a single response that is sent back to the client.

                <figure xml:id="rx.client.motivation.problem">
                    <title>Travel Agency Orchestration Service</title>
                    <mediaobject>
                        <imageobject>
                            <imagedata fileref="images/rx-client-problem.png" format="PNG" width="80%" scalefit="1" align="center"/>
                        </imageobject>
                    </mediaobject>
                </figure>

                The next sections describe various approaches (using JAX-RS Client) how the orchestration layer can be implemented.
            </para>
        </simplesect>

        <simplesect>
            <title>A Naive Approach</title>

            <para>
                The simplest way to implement the orchestration layer is to use synchronous approach. For this purpose we can use
                JAX-RS Client Sync API (see <xref linkend="rx.client.motivation.naive" />). The implementation is simple to do,
                easy to read and straightforward to debug.

                <example xml:id="rx.client.motivation.naive">
                    <title>Excerpt from a synchronous approach while implementing the orchestration layer</title>

                    <programlisting language="java" linenumbering="numbered">final WebTarget destination = ...;
final WebTarget forecast = ...;

// Obtain recommended destinations.
List&lt;Destination&gt; recommended = Collections.emptyList();
try {
    recommended = destination.path("recommended").request()
            // Identify the user.
            .header("Rx-User", "Sync")
            // Return a list of destinations.
            .get(new GenericType&lt;List&lt;Destination&gt;&gt;() {});
} catch (final Throwable throwable) {
    errors.offer("Recommended: " + throwable.getMessage());
}

// Forecasts. (depend on recommended destinations)
final Map&lt;String, Forecast&gt; forecasts = new HashMap&lt;&gt;();
for (final Destination dest : recommended) {
    try {
        forecasts.put(dest.getDestination(),
                forecast.resolveTemplate("destination", dest.getDestination()).request().get(Forecast.class));
    } catch (final Throwable throwable) {
        errors.offer("Forecast: " + throwable.getMessage());
    }
}</programlisting>
                </example>

                The downside of this approach is its slowness. You need to sequentially process all the independent requests which
                means that you're wasting resources. You are needlessly blocking threads, that could be otherwise used for some real work.
            </para>
            <para>
                If you take a closer look at the example you can notice that at the moment when all the recommended destinations are
                available for further processing we try to obtain forecasts for these destinations. Obtaining a weather forecast
                can be done only for a single destination with a single request, so we need to make 10 requests to
                the <emphasis>Forecast service</emphasis> to get all the destinations covered. In a synchronous way this means getting the forecasts
                one-by-one. When one response with a forecast arrives we can send another request to obtain another one. This takes
                time. The whole process of constructing a response for the client can be seen in
                <xref linkend="rx.client.motivation.graph.sync" xrefstyle="select: label" />.
            </para>
            <para>
                Let's try to quantify this with assigning an approximate time to every request we make to the internal services.
                This way we can easily compute the time needed to complete a response for the client. For example, obtaining

                <itemizedlist>
                    <listitem>
                        <para><emphasis>Customer details</emphasis> takes 150 ms</para>
                    </listitem>
                    <listitem>
                        <para><emphasis>Recommended destinations</emphasis> takes 250 ms</para>
                    </listitem>
                    <listitem>
                        <para><emphasis>Price calculation for a customer and destination</emphasis> takes 170 ms (each)</para>
                    </listitem>
                    <listitem>
                        <para><emphasis>Weather forecast for a destination</emphasis> takes 330 ms (each)</para>
                    </listitem>
                </itemizedlist>

                When summed up, 5400 ms is approximately needed to construct a response for the client.

                <figure xml:id="rx.client.motivation.graph.sync">
                    <title>Time consumed to create a response for the client – synchronous way</title>
                    <mediaobject>
                        <imageobject>
                            <imagedata fileref="images/rx-client-sync-approach.png" format="PNG" width="80%" scalefit="1" align="center"/>
                        </imageobject>
                    </mediaobject>
                </figure>

                Synchronous approach is better to use for lower number of requests (where the accumulated time doesn't matter that
                much) or for a single request that depends on the result of previous operations.
            </para>
        </simplesect>

        <simplesect>
            <title>Optimized Approach</title>

            <para>
                The amount of time needed by the synchronous approach can be lowered by invoking independent requests in parallel.
                We're going to use JAX-RS Client Async API to illustrate this approach. The implementation in this case is slightly
                more difficult to get right because of the nested callbacks and the need to wait at some points for the moment
                when all partial responses are ready to be processed. The implementation is also a little bit harder to debug and maintain.
                The nested calls are causing a lot of complexity here. An example of concrete Java code following the asynchronous approach
                can be seen in <xref linkend="rx.client.motivation.optimized" />.

                <example xml:id="rx.client.motivation.optimized">
                    <title>Excerpt from an asynchronous approach while implementing the orchestration layer</title>

                    <programlisting language="java" linenumbering="numbered">final WebTarget destination = ...;
final WebTarget forecast = ...;

// Obtain recommended destinations. (does not depend on visited ones)
destination.path("recommended").request()
        // Identify the user.
        .header("Rx-User", "Async")
        // Async invoker.
        .async()
        // Return a list of destinations.
        .get(new InvocationCallback&lt;List&lt;Destination&gt;&gt;() {
            @Override
            public void completed(final List&lt;Destination&gt; recommended) {
                final CountDownLatch innerLatch = new CountDownLatch(recommended.size());

                // Forecasts. (depend on recommended destinations)
                final Map&lt;String, Forecast&gt; forecasts = Collections.synchronizedMap(new HashMap&lt;&gt;());
                for (final Destination dest : recommended) {
                    forecast.resolveTemplate("destination", dest.getDestination()).request()
                            .async()
                            .get(new InvocationCallback&lt;Forecast&gt;() {
                                @Override
                                public void completed(final Forecast forecast) {
                                    forecasts.put(dest.getDestination(), forecast);
                                    innerLatch.countDown();
                                }

                                @Override
                                public void failed(final Throwable throwable) {
                                    errors.offer("Forecast: " + throwable.getMessage());
                                    innerLatch.countDown();
                                }
                            });
                }

                // Have to wait here for dependent requests ...
                try {
                    if (!innerLatch.await(10, TimeUnit.SECONDS)) {
                        errors.offer("Inner: Waiting for requests to complete has timed out.");
                    }
                } catch (final InterruptedException e) {
                    errors.offer("Inner: Waiting for requests to complete has been interrupted.");
                }

                // Continue with processing.
            }

            @Override
            public void failed(final Throwable throwable) {
                errors.offer("Recommended: " + throwable.getMessage());
            }
        });</programlisting>
                </example>
            </para>
            <para>
                The example is a bit more complicated from the first glance. We provided an &jaxrs.client.InvocationCallback; to async
                <literal>get</literal> method. One of the callback methods (<literal>completed</literal> or <literal>failed</literal>)
                is called when the request finishes. This is a pretty convenient way to handle async invocations when no nested
                calls are present. Since we have some nested calls (obtaining weather forecasts) we needed to introduce
                a &jdk6.CountDownLatch; synchronization primitive as we use asynchronous approach in obtaining the weather
                forecasts as well. The latch is decreased every time a request, to the <emphasis>Forecasts service</emphasis>,
                completes successfully or fails. This indicates that the request actually finished and it is a signal for us that
                we can continue with processing (otherwise we wouldn't have all required data to construct the response for the
                client). This additional synchronization is something that was not present when taking the synchronous approach,
                but it is needed here.
            </para>
            <para>
                Also the error processing can not be written as it could be in an ideal case. The error handling is scattered in
                too many places within the code, that it is quite difficult to create a comprehensive response for the client.
            </para>
            <para>
                On the other hand taking asynchronous approach leads to code that is as fast as it gets.
                The resources are used optimally (no waiting threads) to achieve
                quick response time. The whole process of constructing the response for the client can be seen in
                <xref linkend="rx.client.motivation.graph.async" xrefstyle="select: label" />. It only took 730 ms instead of
                5400 ms which we encountered in the previous approach.

                <figure xml:id="rx.client.motivation.graph.async">
                    <title>Time consumed to create a response for the client – asynchronous way</title>
                    <mediaobject>
                        <imageobject>
                            <imagedata fileref="images/rx-client-async-approach.png" format="PNG" width="80%" scalefit="1" align="center"/>
                        </imageobject>
                    </mediaobject>
                </figure>

                As you can guess, this approach, even with all it's benefits, is the one that is really hard to implement, debug
                and maintain. It's a safe bet when you have many independent calls to make but it gets uglier with an increasing
                number of nested calls.
            </para>
        </simplesect>

        <simplesect>
            <title>Reactive Approach</title>

            <para>
                Reactive approach is a way out of the so-called <emphasis>Callback Hell</emphasis> which you can encounter when
                dealing with Java's <literal>Future</literal>s or invocation callbacks. Reactive approach is based on a data-flow
                concept and the execution model propagate changes through the flow. An example of a single item in the data-flow
                chain can be a JAX-RS Client HTTP method call. When the JAX-RS request finishes then the next item (or the user code)
                in the data-flow chain is notified about the continuation, completion or error in the chain. You're more describing
                what should be done next than how the next action in the chain should be triggered. The other important part here
                is that the data-flows are composable. You can compose/transform multiple flows into the resulting one and apply
                more operations on the result.
            </para>
            <para>
                An example of this approach can be seen in <xref linkend="rx.client.motivation.reactive" />. The APIs would be
                described in more detail in the next sections.

                <example xml:id="rx.client.motivation.reactive">
                    <title>Excerpt from a reactive approach while implementing the orchestration layer</title>

                    <programlisting language="java" linenumbering="numbered">final WebTarget destination = ...;
final WebTarget forecast = ...;

// Recommended places.
CompletionStage&lt;List&lt;Destination&gt;&gt; recommended =
        destination.path("recommended")
                   .request()
                   // Identify the user.
                   .header("Rx-User", "CompletionStage")
                   // Reactive invoker.
                   .rx()
                   // Return a list of destinations.
                   .get(new GenericType&lt;List&lt;Destination&gt;&gt;() {})
                   .exceptionally(throwable -&gt; {
                       errors.offer("Recommended: " + throwable.getMessage());
                       return Collections.emptyList();
                   });

// get Forecast for recommended destinations.
return recommended.thenCompose(destinations -&gt; {

    List&lt;CompletionStage&lt;Recommendation&gt;&gt; recommendations = destinations.stream().map(destination -&gt; {
    // For each destination, obtain a weather forecast ...
    final CompletionStage&lt;Forecast&gt; forecastResult =
            forecast.resolveTemplate("destination", destination.getDestination())
                    .request().rx().get(Forecast.class)
                    .exceptionally(throwable -&gt; {
                        errors.offer("Forecast: " + throwable.getMessage());
                        return new Forecast(destination.getDestination(), "N/A");
                    });

                    //noinspection unchecked
                    return CompletableFuture.completedFuture(new Recommendation(destination))
                                            // Set forecast for recommended destination.
                                            .thenCombine(forecastResult, Recommendation::forecast)
                    }).collect(Collectors.toList());

                    // Transform List&lt;CompletionStage&lt;Recommendation&gt;&gt; to CompletionStage&lt;List&lt;Recommendation&gt;&gt;
                    return sequence(recommendations);
    });</programlisting>

                </example>
            </para>
            <para>
                As you can see the code achieves the same work as the previous two examples. It's more readable than the pure
                asynchronous approach even though it's equally fast. It's as easy to read and implement as the synchronous approach.
                The error processing is also better handled in this way than in the asynchronous approach.
            </para>
            <para>
                When dealing with a large amount of requests (that depend on each other) and when you need to compose/combine the
                results of these requests, the reactive programming model is the right technique to use.
            </para>
        </simplesect>
    </section>

    <section>
        <title>Usage and Extension Modules</title>

        <para>
            Reactive Client API is part of the JAX-RS specification since version 2.1. 
        </para>

        <para>
            When you compare synchronous invocation of HTTP calls (
            <xref linkend="rx.client.sync" />)

            <example xml:id="rx.client.sync">
                <title>Synchronous invocation of HTTP requests</title>

                <programlisting language="java" linenumbering="numbered">Response response = ClientBuilder.newClient()
        .target("http://example.com/resource")
        .request()
        .get();</programlisting>
            </example>

            with asynchronous invocation (<xref linkend="rx.client.async" />)

            <example xml:id="rx.client.async">
                <title>Asynchronous invocation of HTTP requests</title>

                <programlisting language="java" linenumbering="numbered">Future&lt;Response&gt; response = ClientBuilder.newClient()
        .target("http://example.com/resource")
        .request()
        .async()
        .get();</programlisting>
            </example>

            it is apparent how to pretty conveniently modify the way how a request is invoked (from sync to async) only by calling
            <literal>async</literal> method on an &jaxrs.client.Invocation.Builder;.
        </para>
        <para>
            Naturally, it'd be nice to copy the same pattern to allow invoking requests in a reactive way. Just instead of
            <literal>async</literal> you'd call <literal>rx</literal> on an extension of &lit.jaxrs.client.Invocation.Builder;,
            like in <xref linkend="rx.client.reactive" />.

            <example xml:id="rx.client.reactive">
                <title>Reactive invocation of HTTP requests</title>

                <programlisting language="java" linenumbering="numbered">CompletionStage&lt;Response&gt; response = ClientBuilder.newClient()
        .target("http://example.com/resource")
        .request()
        .rx()
        .get();</programlisting>
            </example>
        </para>
        <para>
            The first reactive interface in the invocation chain is &jaxrs.client.RxInvoker; which is very similar to
            &jaxrs.client.SyncInvoker; and &jaxrs.client.AsyncInvoker;. It contains all methods present in the two latter
            JAX-RS interfaces but the &lit.jaxrs.client.RxInvoker; interface is more generic, so that it can be extended
            and used in particular implementations taking advantage of various reactive libraries. Extending this new interface
            in a particular implementation also preserves type safety which means that you're not loosing type information when a HTTP
            method call returns an object that you want to process further.
        </para>
        <para>
            The method "rx()" in the example above is perfect example of that principle. It returns &jaxrs.client.CompletionStageRxInvoker;,
            which extends &jaxrs.client.RxInvoker;.
        </para>
        <para>
            As a user of the Reactive Client API you only need to keep in mind that you won't be working with
            &lit.jaxrs.client.RxInvoker; directly. You'd rather be working with an extension of this interface created for
            a particular implementation and you don't need to be bothered much with why are things designed the way they are.

            <note>
                <para>
                    To see how the &lit.jaxrs.client.RxInvoker; should be extended, refer to
                    <xref linkend="rx.client.spi" />.
                </para>
            </note>

            The important thing to notice here is that an extension of &lit.jaxrs.client.RxInvoker; holds the type
            information and the Reactive Client needs to know about this type to properly propagate it among the method
            calls you'll be making. This is the reason why other interfaces (described bellow) are parametrized with this type.
        </para>
        <para>
            In order to extend the API to be used with other reactive frameworks, &jaxrs.client.RxInvokerProvider; needs to be
            registered into the Client runtime:
        </para>
        <programlisting language="java" linenumbering="numbered">Client client = ClientBuilder.newClient();
client.register(RxFlowableInvokerProvider.class);

Flowable&lt;String&gt; responseFlowable =
        client.target("http://eclipse-ee4j.github.io/jersey")
              .request()
              .rx(RxFlowableInvoker.class)
              .get(String.class);

String responseString = responseFlowable.blockingFirst();</programlisting>        

        <simplesect>
                <title>Dependencies</title>

                <para>
                    JAX-RS mandates support for CompletionStage, which doesn't required any other dependency and can be
                    used out of the box.
                </para>
                <para>
                    To add support for a particular library, see the <xref linkend="rx.client.supported" />.
                </para>

                <note>
                    <para>
                        If you're not using Maven (or other dependency management tool) make sure to add also all the transitive
                        dependencies of Jersey client module and any other extensions (when used) on the class-path.
                    </para>
                </note>
            </simplesect>
    </section>

    <section xml:id="rx.client.supported">
        <title>Supported Reactive Libraries</title>

        <para>
            There are already some available reactive (or reactive-like) libraries out there and Jersey brings support for some of
            them out of the box. Jersey currently supports:

            <itemizedlist>
                <listitem>
                    <para><xref linkend="rx-client.rxjava" endterm="rx-client.rxjava.title" /></para>
                </listitem>
                <listitem>
                    <para><xref linkend="rx-client.rxjava2" endterm="rx-client.rxjava2.title" /></para>
                </listitem>
                <listitem>
                    <para><xref linkend="rx-client.guava" endterm="rx-client.guava.title" /></para>
                </listitem>
            </itemizedlist>
        </para>

        <section xml:id="rx-client.rxjava">
            <title>RxJava – Observable</title>
            <titleabbrev xml:id="rx-client.rxjava.title">RxJava (Observable)</titleabbrev>

            <para>
                &rxjava.link;, contributed by Netflix, is probably the most advanced reactive library for Java at the moment. It's
                used for composing asynchronous and event-based programs by using observable sequences. It uses the
                <link xlink:href="&wikipedia.uri;Observer_pattern">observer pattern</link> to support these sequences of data/events
                via its &rxjava.Observable; entry point class which implements the Reactive Pattern. &lit.rxjava.Observable; is
                actually the parameter type in the RxJava's extension of &jaxrs.client.RxInvoker;, called
                &jersey.ext.rx.client.rxjava.RxObservableInvoker;. This means that the return type of HTTP method calls is
                &lit.rxjava.Observable; in this case (accordingly parametrized).
            </para>
            <para>
                Requests are by default invoked at the moment when a subscriber is subscribed to an observable (it's a cold
                &lit.rxjava.Observable;). If not said otherwise a separate thread (JAX-RS Async Client requests) is used to
                obtain data. This behavior can be overridden by providing an &jdk6.ExecutorService; when a reactive
                &lit.jaxrs.client.Client; is created.
            </para>

            <simplesect>
                <title>Usage</title>

                <para>
                    The extensibility is built-in JAX-RS Client API, so there are no special dependencies on Jersey Client
                    API other than the extension itself.

                    <example xml:id="rx.client.rxjava.rx">
                        <title>Creating JAX-RS Client with RxJava reactive extension</title>

                        <programlisting language="java" linenumbering="numbered">// New Client
Client client = ClientBuilder.newClient();
client.register(RxObservableInvokerProvider.class);</programlisting>
                    </example>
                </para>
                <para>
                    An example of obtaining &lit.rxjava.Observable; with JAX-RS &lit.jaxrs.core.Response; from a remote service
                    can be seen in <xref linkend="rx.client.rxjava.usage" />.

                    <example xml:id="rx.client.rxjava.usage">
                        <title>Obtaining Observable&lt;Response&gt; from Jersey/RxJava Client</title>

                        <programlisting language="java" linenumbering="numbered">Observable&lt;Response&gt; observable = RxObservable.newClient()
                                                    .target("http://example.com/resource")
                                                    .request()
                                                    .rx(RxObservableInvoker.class)
                                                    .get();</programlisting>
                    </example>
                </para>
            </simplesect>

            <simplesect>
                <title>Dependencies</title>

                <para>
                    The RxJava support is available as an extension module in Jersey. For Maven users,
                    simply add the following dependency to your &lit.pom.xml;:

                    <programlisting language="xml" linenumbering="unnumbered">&lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.ext.rx&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-rx-client-rxjava&lt;/artifactId&gt;
    &lt;version&gt;&version;&lt;/version&gt;
&lt;/dependency&gt;</programlisting>

                    After this step you can use the extended client right away. The dependency transitively adds the following
                    dependencies to your class-path as well: <literal>io.reactivex:rxjava</literal>.
                </para>

                <note>
                    <para>
                        If you're not using Maven (or other dependency management tool) make sure to add also all the transitive
                        dependencies of this extension module (see &jersey.ext.rx-client.rxjava.deps.link;) on the class-path.
                    </para>
                </note>
            </simplesect>
        </section>

        <section xml:id="rx-client.rxjava2">
            <title>RxJava – Flowable</title>
            <titleabbrev xml:id="rx-client.rxjava2.title">RxJava (Flowable)</titleabbrev>

            <para>
                &rxjava.link;, contributed by Netflix, is probably the most advanced reactive library for Java at the moment. It's
                used for composing asynchronous and event-based programs by using observable sequences. It uses the
                <link xlink:href="&wikipedia.uri;Observer_pattern">observer pattern</link> to support these sequences of data/events
                via its &rxjava2.Flowable; entry point class which implements the Reactive Pattern. &lit.rxjava2.Flowable; is
                actually the parameter type in the RxJava's extension of &jaxrs.client.RxInvoker;, called
                &jersey.ext.rx.client.rxjava2.RxFlowableInvoker;. This means that the return type of HTTP method calls is
                &lit.rxjava2.Flowable; in this case (accordingly parametrized).
            </para>
            <para>
                Requests are by default invoked at the moment when a subscriber is subscribed to a flowable (it's a cold
                &lit.rxjava2.Flowable;). If not said otherwise a separate thread (JAX-RS Async Client requests) is used to
                obtain data. This behavior can be overridden by providing an &jdk6.ExecutorService; when a reactive
                &lit.jaxrs.client.Client; is created.
            </para>

            <simplesect>
                <title>Usage</title>

                <para>
                    The extensibility is built-in JAX-RS Client API, so there are no special dependencies on Jersey Client
                    API other than the extension itself.

                    <example xml:id="rx.client.rxjava2.rx">
                        <title>Creating JAX-RS Client with RxJava2 reactive extension</title>

                        <programlisting language="java" linenumbering="numbered">// New Client
Client client = ClientBuilder.newClient();
client.register(RxFlowableInvokerProvider.class);</programlisting>
                    </example>
                </para>
                <para>
                    An example of obtaining &lit.rxjava2.Flowable; with JAX-RS &lit.jaxrs.core.Response; from a remote service
                    can be seen in <xref linkend="rx.client.rxjava.usage" />.

                    <example xml:id="rx.client.rxjava2.usage">
                        <title>Obtaining Flowable&lt;Response&gt; from Jersey/RxJava Client</title>

                        <programlisting language="java" linenumbering="numbered">Flowable&lt;Response&gt; observable = RxObservable.newClient()
                            .target("http://example.com/resource")
                            .request()
                            .rx(RxFlowableInvoker.class)
                            .get();
                        </programlisting>
                    </example>
                </para>
            </simplesect>

            <simplesect>
                <title>Dependencies</title>

                <para>
                    The RxJava support is available as an extension module in Jersey. For Maven users,
                    simply add the following dependency to your &lit.pom.xml;:

                    <programlisting language="xml" linenumbering="unnumbered">&lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.ext.rx&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-rx-client-rxjava2&lt;/artifactId&gt;
    &lt;version&gt;&version;&lt;/version&gt;
&lt;/dependency&gt;</programlisting>

                    After this step you can use the extended client right away. The dependency transitively adds the following
                    dependencies to your class-path as well: <literal>io.reactivex:rxjava2</literal>.
                </para>

                <note>
                    <para>
                        If you're not using Maven (or other dependency management tool) make sure to add also all the transitive
                        dependencies of this extension module (see &jersey.ext.rx-client.rxjava2.deps.link;) on the class-path.
                    </para>
                </note>
            </simplesect>
        </section>

        <section xml:id="rx-client.guava">
            <title>Guava – ListenableFuture and Futures</title>
            <titleabbrev xml:id="rx-client.guava.title">Guava (ListenableFuture and Futures)</titleabbrev>

            <para>
                &guava.link;, contributed by Google, also contains a type, &guava.ListenableFuture;, which can be decorated with
                listeners that are notified when the future completes. The &lit.guava.ListenableFuture; can be combined with
                &guava.Futures; to achieve asynchronous/event-based completion aware processing. &lit.guava.ListenableFuture;
                is the parameter type in the Guava's extension of &lit.jaxrs.client.RxInvoker;, called
                &jersey.ext.rx.client.guava.RxListenableFutureInvoker;. This means that the return type of HTTP method calls is
                &lit.guava.ListenableFuture; in this case (accordingly parametrized).
            </para>
            <para>
                Requests are by default invoked immediately. If not said otherwise the &jdk8.Executors.newCachedThreadPool; pool
                is used to obtain a thread which processed the request. This behavior can be overridden by providing a
                &jdk6.ExecutorService; when a &lit.jaxrs.client.Client; is created.
            </para>

            <simplesect>
                <title>Usage</title>

                <para>
                    The extensibility is built-in JAX-RS Client API, so there are no special dependencies on Jersey Client
                    API other than the extension itself.

                    <example xml:id="rx.client.guava.rx">
                        <title>Creating Jersey/Guava Client</title>

                        <programlisting language="java" linenumbering="numbered">// New Client
Client client = ClientBuilder.newClient();
client.register(RxListenableFutureInvokerProvider.class);</programlisting>
                    </example>
                </para>
                <para>
                    An example of obtaining &lit.guava.ListenableFuture; with JAX-RS &lit.jaxrs.core.Response; from a remote
                    service can be seen in <xref linkend="rx.client.guava.usage" />.

                    <example xml:id="rx.client.guava.usage">
                        <title>Obtaining ListenableFuture&lt;Response&gt; from Jersey/Guava Client</title>

                        <programlisting language="java" linenumbering="numbered">
ListenableFuture&lt;Response&gt; response = client.target("http://eclipse-ee4j.github.io/jersey")
                                            .request()
                                            .rx(RxListenableFutureInvoker.class)
                                            .get();
</programlisting>
                    </example>
                </para>
            </simplesect>

            <simplesect>
                <title>Dependencies</title>

                <para>
                    The Reactive Jersey Client with Guava support is available as an extension module in Jersey. For Maven users,
                    simply add the following dependency to your &lit.pom.xml;:

                    <programlisting language="xml" linenumbering="unnumbered">&lt;dependency&gt;
    &lt;groupId&gt;org.glassfish.jersey.ext.rx&lt;/groupId&gt;
    &lt;artifactId&gt;jersey-rx-client-guava&lt;/artifactId&gt;
    &lt;version&gt;&version;&lt;/version&gt;
&lt;/dependency&gt;</programlisting>

                    After this step you can use the extended client right away. The dependency transitively adds the following
                    dependencies to your class-path as well: <literal>com.google.guava:guava</literal>.
                </para>

                <note>
                    <para>
                        If you're not using Maven (or other dependency management tool) make sure to add also all the transitive
                        dependencies of this extension module (see &jersey.ext.rx-client.guava.deps.link;) on the class-path.
                    </para>
                </note>
            </simplesect>
        </section>

    </section>

    <section xml:id="rx.client.spi">
        <title>Implementing Support for Custom Reactive Libraries (SPI)</title>

        <para>
            In case you want to bring support for some other library providing Reactive Programming Model into your application
            you can extend functionality of Reactive JAX-RS Client by implementing &jaxrs.client.RxInvokerProvider;, registering
            that implementation into the client runtime and then using rx(Class&lt;T&gt;) in your code.
        </para>

        <simplesect>
            <title>Implement RxInvoker and RxInvokerProvider interfaces</title>

            <para>
                The first step when implementing support for another reactive library is to implement &jaxrs.client.RxInvoker;.
                JAX-RS API itself contains one implementation, which will be used as an example: &jaxrs.client.CompletionStageRxInvoker;.

                <example xml:id="rx.client.rxinvoker">
                    <title>Extending RxIvoker</title>

                    <programlisting language="java" linenumbering="numbered">public interface CompletionStageRxInvoker extends RxInvoker&lt;CompletionStage&gt; {
    @Override
    public CompletionStage&lt;Response&gt; get();

    @Override
    public &lt;T&gt; CompletionStage&lt;T&gt; get(Class&lt;T&gt; responseType);

    // ...
}</programlisting>
                </example>
            </para>
            <para>
                The important fact to notice is that the generic parameter of &jaxrs.client.RxInvoker; is &jdk8.CompletionStage;
                and also that the return type is overriden to be always &jdk8.CompletionStage; with some generic param (&jaxrs.core.Response;;
                or T).
            </para>
            <para>
                After having the extended RxInvoker interface, the implementor has to provide &jaxrs.client.RxInvokerProvider;,
                which will be registered as an provider to a client instance.
            </para>
            <example xml:id="rx.client.extend.rxinvoker">
            <title>Extending RxInvokerProvider</title>

            <programlisting language="java" linenumbering="numbered">public static class CompletionStageRxInvokerProvider implements RxInvokerProvider&lt;CompletionStageRxInvoker&gt; {
    @Override
    public boolean isProviderFor(Class&lt;?&gt; clazz) {
        return CompletionStage.class.equals(clazz);
    }

    @Override
    public CompletionStageRxInvoker getRxInvoker(SyncInvoker syncInvoker, ExecutorService executorService) {
        return new CompletionStageRxInvoker() {
            // ...
        };
    }
}</programlisting></example>
        </simplesect>
        <simplesect>
            <title>Example of using custom RxInvokerProvider</title>

            <para>
                Considering the work above was done and the implementation of custom &lit.jaxrs.client.RxInvoker; and
                &lit.jaxrs.client.RxInvokerProvider; is available, the client code using those extensions will be:
            </para>
            <programlisting language="java" linenumbering="numbered">Client client = ClientBuilder.newClient();
// register custom RxInvokerProvider
client.register(CompletionStageRxInvokerProvider.class);

CompletionStage&lt;Response&gt; response =
        client.target("http://eclipse-ee4j.github.io/jersey")
              .request()
              .rx(CompletionStageRxInvoker.class)
              // Now we have an instance of CompletionStageRxInvoker returned from our registered RxInvokerProvider,
              // which is CompletionStageRxInvokerProvider in this particular scenario.
              .get();</programlisting>

        </simplesect>
    </section>
</chapter>
