Back to Dropwizard

Dropwizard Client

docs/source/manual/client.rst

5.0.19.8 KB
Original Source

.. _man-client:

################# Dropwizard Client #################

.. highlight:: text

.. rubric:: The dropwizard-client module provides you with two different performant, instrumented HTTP clients so you can integrate your service with other web services: :ref:man-client-apache and :ref:man-client-jersey.

.. code-block:: xml

<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-client</artifactId>
</dependency>

.. _man-client-apache:

Apache HttpClient

The underlying library for dropwizard-client is Apache's HttpClient_, a full-featured, well-tested HTTP client library.

.. _HttpClient: https://hc.apache.org/httpcomponents-client-4.5.x/index.html

To create a :ref:managed <man-core-managed>, instrumented HttpClient instance, your :ref:configuration class <man-core-configuration> needs an :ref:http client configuration <man-configuration-clients-http> instance:

.. code-block:: java

public class ExampleConfiguration extends Configuration {
    @Valid
    @NotNull
    private HttpClientConfiguration httpClient = new HttpClientConfiguration();

    @JsonProperty("httpClient")
    public HttpClientConfiguration getHttpClientConfiguration() {
        return httpClient;
    }

    @JsonProperty("httpClient")
    public void setHttpClientConfiguration(HttpClientConfiguration httpClient) {
        this.httpClient = httpClient;
    }
}

Then, in your application's run method, create a new HttpClientBuilder:

.. code-block:: java

@Override
public void run(ExampleConfiguration config,
                Environment environment) {
    final HttpClient httpClient = new HttpClientBuilder(environment).using(config.getHttpClientConfiguration())
                                                                    .build(getName());
    environment.jersey().register(new ExternalServiceResource(httpClient));
}

.. _man-client-apache-metrics:

Metrics

Dropwizard's HttpClientBuilder actually gives you an instrumented subclass which tracks the following pieces of data:

org.apache.http.conn.ClientConnectionManager.available-connections The number of idle connections ready to be used to execute requests.

org.apache.http.conn.ClientConnectionManager.leased-connections The number of persistent connections currently being used to execute requests.

org.apache.http.conn.ClientConnectionManager.max-connections The maximum number of allowed connections.

org.apache.http.conn.ClientConnectionManager.pending-connections The number of connection requests being blocked awaiting a free connection.

org.apache.http.client.HttpClient.get-requests The rate at which GET requests are being sent.

org.apache.http.client.HttpClient.post-requests The rate at which POST requests are being sent.

org.apache.http.client.HttpClient.head-requests The rate at which HEAD requests are being sent.

org.apache.http.client.HttpClient.put-requests The rate at which PUT requests are being sent.

org.apache.http.client.HttpClient.delete-requests The rate at which DELETE requests are being sent.

org.apache.http.client.HttpClient.options-requests The rate at which OPTIONS requests are being sent.

org.apache.http.client.HttpClient.trace-requests The rate at which TRACE requests are being sent.

org.apache.http.client.HttpClient.connect-requests The rate at which CONNECT requests are being sent.

org.apache.http.client.HttpClient.move-requests The rate at which MOVE requests are being sent.

org.apache.http.client.HttpClient.patch-requests The rate at which PATCH requests are being sent.

org.apache.http.client.HttpClient.other-requests The rate at which requests with none of the above methods are being sent.

.. note::

The naming strategy for the metrics associated requests is configurable.
Specifically, the last part e.g. get-requests.
What is displayed is ``HttpClientMetricNameStrategies.METHOD_ONLY``, you can
also include the host via ``HttpClientMetricNameStrategies.HOST_AND_METHOD``
or a url without query string via ``HttpClientMetricNameStrategies.QUERYLESS_URL_AND_METHOD``

.. _man-client-jersey:

Jersey Client

If HttpClient_ is too low-level for you, Dropwizard also supports Jersey's Client API_. Jersey's Client allows you to use all of the server-side media type support that your service uses to, for example, deserialize application/json request entities as POJOs.

.. _Client API: https://eclipse-ee4j.github.io/jersey.github.io/documentation/2.29.1/client.html

To create a :ref:managed <man-core-managed>, instrumented JerseyClient instance, your :ref:configuration class <man-core-configuration> needs an :ref:jersey client configuration <man-configuration-clients-jersey> instance:

.. code-block:: java

public class ExampleConfiguration extends Configuration {
    @Valid
    @NotNull
    private JerseyClientConfiguration jerseyClient = new JerseyClientConfiguration();

    @JsonProperty("jerseyClient")
    public JerseyClientConfiguration getJerseyClientConfiguration() {
        return jerseyClient;
    }

    @JsonProperty("jerseyClient")
    public void setJerseyClientConfiguration(JerseyClientConfiguration jerseyClient) {
        this.jerseyClient = jerseyClient;
    }
}

Then, in your service's run method, create a new JerseyClientBuilder:

.. code-block:: java

@Override
public void run(ExampleConfiguration config,
                Environment environment) {

    final Client client = new JerseyClientBuilder(environment).using(config.getJerseyClientConfiguration())
                                                              .build(getName());
    environment.jersey().register(new ExternalServiceResource(client));
}

Configuration

The Client that Dropwizard creates deviates from the Jersey Client Configuration defaults. The default, in Jersey, is for a client to never timeout reading or connecting in a request, while in Dropwizard, the default is 500 milliseconds.

There are a couple of ways to change this behavior. The recommended way is to modify the :ref:YAML configuration <man-configuration-clients-http>. Alternatively, set the properties on the JerseyClientConfiguration, which will take effect for all built clients. On a per client basis, the configuration can be changed by utilizing the property method and, in this case, the Jersey Client Properties_ can be used.

.. warning::

Do not try to change Jersey properties using `Jersey Client Properties`_ through the

``withProperty(String propertyName, Object propertyValue)``

method on the ``JerseyClientBuilder``, because by default it's configured by Dropwizard's
``HttpClientBuilder``, so the Jersey properties are ignored.

.. _Jersey Client Configuration: https://eclipse-ee4j.github.io/jersey.github.io/documentation/2.29.1/appendix-properties.html#appendix-properties-client .. _Jersey Client Properties: https://eclipse-ee4j.github.io/jersey.github.io/apidocs/2.29.1/jersey/org/glassfish/jersey/client/ClientProperties.html

.. _man-client-jersey-rx-usage:

Rx Usage

To increase the ergonomics of asynchronous client requests, Jersey allows creation of rx-clients_. You can instruct Dropwizard to create such a client (RxJava2):

.. code-block:: java

@Override
public void run(ExampleConfiguration config,
                Environment environment) {

    final Client client =
        new JerseyClientBuilder(environment)
            .using(config.getJerseyClientConfiguration())
            .buildRx(getName(), RxFlowableInvokerProvider.class);
    //Any custom Service Resource that waits for Client in constructor      
    environment.jersey().register(new ExternalServiceResource(client));
}

RxFlowableInvokerProvider.class is the JavaRx implementation and can be added to the pom:

.. code-block:: xml

<dependency>
    <groupId>org.glassfish.jersey.ext.rx</groupId>
    <artifactId>jersey-rx-client-rxjava2</artifactId>
</dependency>

Alternatively, there are RxJava, Guava, and JSR-166e implementations.

By allowing Dropwizard to create the rx-client, the same thread pool that is utilized by traditional synchronous and asynchronous requests, is used for rx requests.

.. _rx-clients: https://eclipse-ee4j.github.io/jersey.github.io/documentation/2.29.1/rx-client.html

Proxy Authentication

The client can utilise a forward proxy, supporting both Basic and NTLM authentication schemes. Basic Auth against a proxy is simple:

.. code-block:: yaml

 proxy:
      host: '192.168.52.11'
      port: 8080
      scheme : 'https'
      auth:
        username: 'secret'
        password: 'stuff'
      nonProxyHosts:
        - 'localhost'
        - '192.168.52.*'
        - '*.example.com'

NTLM Auth is configured by setting the relevant windows properties.

.. code-block:: yaml

 proxy:
      host: '192.168.52.11'
      port: 8080
      scheme : 'https'
      auth:
        username: 'secret'
        password: 'stuff'
        authScheme: 'NTLM'
        realm: 'realm'                    # optional, defaults to ANY_REALM
        hostname: 'workstation'           # optional, defaults to null but may be required depending on your AD environment
        domain: 'HYPERCOMPUGLOBALMEGANET' # optional, defaults to null but may be required depending on your AD environment
        credentialType: 'NT'
      nonProxyHosts:
        - 'localhost'
        - '192.168.52.*'
        - '*.example.com'