Class ClientSupport

All Implemented Interfaces:
AutoCloseable

public class ClientSupport extends TestClient<ClientSupport> implements AutoCloseable
JerseyClient support for direct web tests (complete dropwizard startup).

Client support maintains single JerseyClient instance. It may be used for calling any urls (not just application). Class provides many utility methods for automatic construction of base context paths, so tests could be completely independent of actual configuration.

Client customization is possible through custom TestClientFactory implementation.

Dropwizard configurations for rest, app and admin contexts:

  • server.applicationContextPath - app context path ("/" by default, "/application" for simple server)
  • server.adminContextPath - admin context path ("/" by default, "/admin" for simple server)
  • server.rootPath - rest context path ("/" by default)
The rest prefix is server.applicationContextPath + server.rootPath.

The class provides access for 4 clients (with the same api TestClient):

  • ClientSupport itself is a client for application root
  • restClient() specialized rest client (mapped rest path counted)
  • appClient() client for the app context (context mapping path counted)
  • adminClient() client for the admin context (context mapping path and port counted)
The main idea of clients is the ability to create a client for any base path to shorten urls in tests. Also, each client could declare its own defaults, applied to all requests (for example, useful for authorization).

There is also a specialized externalClient(String, Object...) for custom clients for creating remote api clients (with the same client api): support.externalClient("http://localhost:8080/some/path").get("/some/resource").

There is a special class-based client constructor restClient(Class) for resources. This makes tests type-safe as the target resource path is obtained directly from the class annotation. Also, such clients could use resource class method calls for request configuration (ResourceClient.method(ru.vyarus.dropwizard.guice.url.util.Caller)).

Note: defaults, declared on root ClientSupport class would be inherited by sub clients (excluding external clients).

The root client is not much useful, so the assumed usage is to get the required client and use it for actual calls.

Class also provides base urls and related jersey targets (pure jersey api):

Since:
04.05.2020
See Also:
  • Constructor Details

    • ClientSupport

      public ClientSupport(io.dropwizard.testing.DropwizardTestSupport<?> support)
      Create a client.
      Parameters:
      support - dropwizard test support
    • ClientSupport

      public ClientSupport(io.dropwizard.testing.DropwizardTestSupport<?> support, @Nullable TestClientFactory factory)
      Create client with custom factory.
      Parameters:
      support - dropwizard test support
      factory - custom client factory
    • ClientSupport

      public ClientSupport(io.dropwizard.testing.DropwizardTestSupport<?> support, @Nullable TestClientFactory factory, @Nullable TestRequestConfig defaults)
      Create client with custom factory.
      Parameters:
      support - dropwizard test support
      factory - custom client factory
      defaults - defaults for all clients (could be overridden by the client-specific defaults)
  • Method Details

    • getClient

      public org.glassfish.jersey.client.JerseyClient getClient()
      Single client instance maintained within test and method will always return the same instance.
      Returns:
      client instance
    • apacheClient

      public ClientSupport apacheClient()
      Shortcut to be able to quickly build an apache-connector-based client. The default urlconnector-based client is better for multipart calls (apache client has problems). But the apache client is better for PATCH calls because the default urlconnector will complain on java > 16.

      With this shortcut it would be possible to use both clients in one test.

      Applied defaults are inherited.

      Returns:
      client based on apache connector
    • urlconnectorClient

      public ClientSupport urlconnectorClient()
      Shortcut to be able to quickly build an apache-connector-based client. The default urlconnector-based client is better for multipart calls (apache client has problems). But the apache client is better for PATCH calls because the default urlconnector will complain on java > 16.

      With this shortcut it would be possible to use both clients in one test.

      Applied defaults are inherited.

      Returns:
      client based on apache connector
    • getPort

      public int getPort()
      Returns:
      app context port
      Throws:
      NullPointerException - for guicey test (when web not started)
    • getAdminPort

      public int getAdminPort()
      Returns:
      admin context port
      Throws:
      NullPointerException - for guicey test (when web not started)
    • basePathRoot

      public String basePathRoot()
      Root application path is, usually, not very interesting so consider using basePathApp(), basePathRest() or basePathAdmin() instead.
      Returns:
      root application path (localhost + port)
      Throws:
      NullPointerException - for guicey test (when web not started)
    • basePathMain

      @Deprecated public String basePathMain()
      Deprecated.
      Returns:
      base path for application context
    • basePathApp

      public String basePathApp()
      For example, with the default configuration it would be "http://localhost:8080/". If "server.applicationContextPath" is changed to "/someth", then the method will return "http://localhost:8080/someth/".

      Returned path will always end with a slash.

      Returns:
      base path for app context
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • basePathAdmin

      public String basePathAdmin()
      For example, with the default configuration it would be "http://localhost:8081/". For the "simple" server, it would be "http://localhost:8080/adminPath/". If "server.adminContextPath" is changed to "/adm", then the method will return "http://localhost:8081/adm/" for the default server and "http://localhost:8080/adm/" for "simple" server.

      Returned path will always end with a slash.

      Returns:
      base path for admin context
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • basePathRest

      public String basePathRest()
      For example, with the default configuration it would be "http://localhost:8080/". If "server.rootPath" is changed to "/api", then the method will return "http://localhost:8080/api/". If the app context mapping changed from root, then the returned path will count it too (e.g. "http://localhost:8080/root/rest/", when "server.applicationContextPath" is "/root").

      Returned path will always end with a slash.

      Returns:
      base path for rest
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • target

      public jakarta.ws.rs.client.WebTarget target(String path, Object... args)
      Create a jersey WebTarget for a path, relative to application root (e.g. "http://localhost:8080/" + provided path)".

      It could be also used to request any external api, for example: target("http://somewhere.com/api/smth/").request().buildGet().invoke().

      String format could be used to format the path: .target("/smth/%s/other", 12).request().buildGet().invoke()

      NOTE: could be used with guicey-only tests (when web part not started) to call any external url.

      IMPORTANT: it would not apply configured defaults (like TestClientDefaults.defaultHeader(String, Object)). Use builders (TestClient.build(String, String, Object, Object...)) or shortcuts TestClient.get(String, Class, Object...) to cal with defaults.

      Overrides:
      target in class TestClient<ClientSupport>
      Parameters:
      path - target path, relative to client root or absolute external path (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      jersey web target object
      See Also:
    • targetMain

      @Deprecated public jakarta.ws.rs.client.WebTarget targetMain(String path, Object... args)
      Deprecated.
      Shortcut for WebTarget creation for the application context path.
      Parameters:
      path - target path, relative to the admin context (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      jersey web target object for the admin context
    • targetApp

      public jakarta.ws.rs.client.WebTarget targetApp(String path, Object... args)
      Shortcut for WebTarget creation for the app context path.

      Example: .targetApp("/path").request().buildGet().invoke() would call "http://localhost:8080/path" (or, if root context mapping changed with server.applicationContextPath = "root", "http://localhost:8080/root/path").

      String format could be used to format the path: .targetApp("/smth/%s/other", 12).request().buildGet().invoke()

      IMPORTANT: it would not apply configured defaults (like TestClientDefaults.defaultHeader(String, Object)). Use app client appClient() to call with defaults.

      Parameters:
      path - target path, relative to the app context (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      jersey web target object for the app context
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • targetAdmin

      public jakarta.ws.rs.client.WebTarget targetAdmin(String path, Object... args)
      Shortcut for WebTarget creation for the admin context path.

      Example: .targetAdmin("/path").request().buildGet().invoke() would call "http://localhost:8081/path" (or, if admin context mapping changed with server.adminContextPath = "admin", "http://localhost:8081/admin/path").

      String format could be used to format the path: .targetAdmin("/smth/%s/other", 12).request().buildGet().invoke()

      IMPORTANT: it would not apply configured defaults (like TestClientDefaults.defaultHeader(String, Object)). Use admin client adminClient() to call with defaults.

      Parameters:
      path - target path, relative to the admin context (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      jersey web target object for the admin context
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • targetRest

      public jakarta.ws.rs.client.WebTarget targetRest(String path, Object... args)
      Shortcut for WebTarget creation for the rest context path.

      Example: .targetRest("/path").request().buildGet().invoke() would call "http://localhost:8080/path" (or, if rest context mapping changed with server.rootPath = "api", "http://localhost:8081/api/path").

      String format could be used to format the path: .targetRest("/smth/%s/other", 12).request().buildGet().invoke()

      IMPORTANT: it would not apply configured defaults (like TestClientDefaults.defaultHeader(String, Object)). Use rest client restClient() (or specialized restClient(Class)) to call with defaults.

      Parameters:
      path - target path, relative to the rest context (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      jersey web target object for rest context
      Throws:
      NullPointerException - for guicey test (when web not started)
      See Also:
    • restClient

      public TestClient<?> restClient()
      Construct a rest client. Client would be configured with the current rest path root (@link basePathRest()), so requests would need to use only relative paths.

      Typed rest client could be obtained from this generic client: restClient().subClient(Resource.class);

      Inherits current defaults (like TestClientDefaults.defaultHeader(String, Object).

      Returns:
      rest client
    • restClient

      public <K> ResourceClient<K> restClient(Class<K> resource)
      Construct a specialized rest client for the given resource class. Client would be configured with the current rest path root (@link basePathRest()) together with the resource class path (obtained from annotation), so requests would need to use paths, relative to resource.

      Also, such client provide methods to configure requests direct from resource methods ResourceClient.method(ru.vyarus.dropwizard.guice.url.util.Caller).

      Inherits current defaults (like TestClientDefaults.defaultHeader(String, Object).

      Overrides:
      restClient in class TestClient<ClientSupport>
      Type Parameters:
      K - resource type
      Parameters:
      resource - resource class to configure target url from
      Returns:
      rest client for the given resource class
    • appClient

      public TestClient<?> appClient()
      Construct a client for the app context. Client would be configured with the current app context path root (@link basePathApp()), so requests would need to use only relative paths.

      Note: by default, root client ClientSupport itself and app context client would be the same, because usually app context is "/". But, you can still prefer app client to shield from potential app context path changes.

      Inherits current defaults (like TestClientDefaults.defaultHeader(String, Object).

      Returns:
      app client
    • adminClient

      public TestClient<?> adminClient()
      Construct a client for the admin context. Client would be configured with the current admin context path root (@link basePathAdmin()), so requests would need to use only relative paths.

      Inherits current defaults (like TestClientDefaults.defaultHeader(String, Object).

      Returns:
      admin client
    • externalClient

      public TestClient<?> externalClient(String url, Object... args)
      Construct a client for external url.

      Example of variables usage: externalClient("http://localhost:8080/%s/other", 12).

      Will not inherit current defaults.

      Parameters:
      url - external url, started with "http(s)" (could contain String.format() placeholders: %s)
      args - variables for path placeholders (String.format() arguments)
      Returns:
      client for the given external url
    • close

      public void close() throws Exception
      Specified by:
      close in interface AutoCloseable
      Throws:
      Exception
    • getRoot

      protected jakarta.ws.rs.client.WebTarget getRoot()
      Description copied from class: TestClient
      Subclasses could override this method: this is required because it is not always possible to provide the correct root target in the constructor (when this method is overridden root, provided in the constructor is null).
      Overrides:
      getRoot in class TestClient<ClientSupport>
      Returns:
      root target