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

    Copyright (c) 2014, 2020 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.
        </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://jersey.java.net")
              .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://jersey.java.net")
                                            .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://jersey.java.net")
              .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>
