Module jdk.incubator.httpclient
Package jdk.incubator.http

## Interface HttpResponse.MultiProcessor<U,T>

- Type Parameters:
    `U` - a type representing the aggregated results
    `T` - a type representing all of the response bodies
  Enclosing class:
    HttpResponse<T>

      public static interface HttpResponse.MultiProcessor<U,T>

  A response processor for a HTTP/2 multi response.
  Incubating Feature. Will be removed in a future release.

  A multi response comprises a main response, and zero or more additional responses. Each additional response is sent by the server in response to requests that the server also generates. Additional responses are typically resources that the server expects the client will need which are related to the initial request.

  Note. Instead of implementing this interface, applications should consider first using the mechanism (built on this interface) provided by `MultiProcessor.asMap()` which is a slightly simplified, but general purpose interface.

  The server generated requests are also known as push promises. The server is permitted to send any number of these requests up to the point where the main response is fully received. Therefore, after completion of the main response, the final number of additional responses is known. Additional responses may be canceled, but given that the server does not wait for any acknowledgment before sending the response, this must be done quickly to avoid unnecessary data transmission.

  `MultiProcessor`s are parameterized with a type `U` which represents some meaningful aggregate of the responses received. This would typically be a collection of response or response body objects.

  Since:
    9

- - ### Method Summary

    All Methods Static Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `static <V> HttpResponse.MultiProcessor<MultiMapResult<V>,V>` | `asMap​(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler)` | Returns a general purpose handler for multi responses.
    `static <V> HttpResponse.MultiProcessor<MultiMapResult<V>,V>` | `asMap​(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler, boolean completion)` | Returns a general purpose handler for multi responses.
    `CompletableFuture<U>` | `completion​(CompletableFuture<Void> onComplete, CompletableFuture<Void> onFinalPushPromise)` | Returns a `CompletableFuture``<U>` which completes when the aggregate result object itself is available.
    `void` | `onError​(HttpRequest request, Throwable t)` | Called if an error occurs receiving a response.
    `Optional<HttpResponse.BodyHandler<T>>` | `onRequest​(HttpRequest request)` | Called for the main request and each push promise that is received.
    `void` | `onResponse​(HttpResponse<T> response)` | Called for each response received.

- - ### Method Detail

    - #### onRequest

          Optional<HttpResponse.BodyHandler<T>> onRequest​(HttpRequest request)

      Called for the main request and each push promise that is received. The first call will always be for the main request that was sent by the caller. This `HttpRequest` parameter represents the initial request or subsequent PUSH_PROMISE. The implementation must return an `Optional` of `HttpResponse.BodyHandler` for the response body. Different handlers (of the same type) can be returned for different pushes within the same multi send. If no handler (an empty `Optional`) is returned, then the push will be canceled. It is an error to not return a valid `BodyHandler` for the initial (main) request.
      Parameters:
        `request` - the main request or subsequent push promise
      Returns:
        an optional body handler

    - #### onResponse

          void onResponse​(HttpResponse<T> response)

      Called for each response received. For each request either one of onResponse() or onError() is guaranteed to be called, but not both. [Note] The reason for switching to this callback interface rather than using CompletableFutures supplied to onRequest() is that there is a subtle interaction between those CFs and the CF returned from completion() (or when onComplete() was called formerly). The completion() CF will not complete until after all of the work done by the onResponse() calls is done. Whereas if you just create CF's dependent on a supplied CF (to onRequest()) then the implementation has no visibility of the dependent CFs and can't guarantee to call onComplete() (or complete the completion() CF) after the dependent CFs complete.
      Parameters:
        `response` - the response received

    - #### onError

          void onError​(HttpRequest request,
                       Throwable t)

      Called if an error occurs receiving a response. For each request either one of onResponse() or onError() is guaranteed to be called, but not both.
      Parameters:
        `request` - the main request or subsequent push promise
        `t` - the Throwable that caused the error

    - #### completion

          CompletableFuture<U> completion​(CompletableFuture<Void> onComplete,
                                          CompletableFuture<Void> onFinalPushPromise)

      Returns a `CompletableFuture``<U>` which completes when the aggregate result object itself is available. It is expected that the returned `CompletableFuture` will depend on one of the given `CompletableFuture<Void`s which themselves complete after all individual responses associated with the multi response have completed, or after all push promises have been received.

      Implementation Note:
        Implementations might follow the pattern shown below

                  CompletableFuture<U> completion(
                          CompletableFuture<Void> onComplete,
                          CompletableFuture<Void> onFinalPushPromise)
                  {
                      return onComplete.thenApply((v) -> {
                          U u = ... instantiate and populate a U instance
                          return u;
                      });
                  }

      Parameters:
        `onComplete` - a CompletableFuture which completes after all responses have been received relating to this multi request.
        `onFinalPushPromise` - CompletableFuture which completes after all push promises have been received.
      Returns:
        the aggregate CF response object

    - #### asMap

          static <V> HttpResponse.MultiProcessor<MultiMapResult<V>,V> asMap​(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler,
                                                                            boolean completion)

      Returns a general purpose handler for multi responses. The aggregated result object produced by this handler is a `Map<HttpRequest,CompletableFuture<HttpResponse<V>>>`. Each request (both the original user generated request and each server generated push promise) is returned as a key of the map. The value corresponding to each key is a `CompletableFuture<HttpResponse<V>>`.

      There are two ways to use these handlers, depending on the value of the completion parameter. If completion is true, then the aggregated result will be available after all responses have themselves completed. If completion is false, then the aggregated result will be available immediately after the last push promise was received. In the former case, this implies that all the CompletableFutures in the map values will have completed. In the latter case, they may or may not have completed yet.

      The simplest way to use these handlers is to set completion to `true`, and then all (results) values in the Map will be accessible without blocking.

      See `asMap(java.util.function.Function, boolean)` for a code sample of using this interface.

      Type Parameters:
        `V` - the body type used for all responses
      Parameters:
        `pushHandler` - a function invoked for each request or push promise
        `completion` - `true` if the aggregate CompletableFuture completes after all responses have been received, or `false` after all push promises received.
      Returns:
        a MultiProcessor

    - #### asMap

          static <V> HttpResponse.MultiProcessor<MultiMapResult<V>,V> asMap​(Function<HttpRequest,Optional<HttpResponse.BodyHandler<V>>> pushHandler)

      Returns a general purpose handler for multi responses. This is a convenience method which invokes `asMap(Function, true)` meaning that the aggregate result object completes after all responses have been received.

      Example usage:

                    HttpRequest request = HttpRequest.newBuilder()
                            .uri(URI.create("https://www.foo.com/"))
                            .GET()
                            .build();

                    HttpClient client = HttpClient.newHttpClient();

                    Map<HttpRequest,CompletableFuture<HttpResponse<String>>> results = client
                        .sendAsync(request, MultiProcessor.asMap(
                            (req) -> Optional.of(HttpResponse.BodyHandler.asString())))
                        .join();

      The lambda in this example is the simplest possible implementation, where neither the incoming requests are examined, nor the response headers, and every push that the server sends is accepted. When the join() call returns, all `HttpResponse`s and their associated body objects are available.

      Type Parameters:
        `V` - the body type used for all responses
      Parameters:
        `pushHandler` - a function invoked for each request or push promise
      Returns:
        a MultiProcessor