How many times have you had to write a server-side test that gets a connection just to check if your configuration is valid and your app can connect to your database?

In the April 2017 beta we introduced a REST API for the configuration validation (Validator) feature. You can use the API to perform tests to check that supported elements of your configuration are valid. This initial beta release of the feature addresses one of the most common use cases: JDBC data sources.

Let’s take a look at how you can use this new REST API to validate your data source configuration.

Example server configuration

This is some sample server.xml configuration that will enable validator-1.0 and jdbc-4.1. This allows you to use API discovery to test out a JDBC connection:

<server>
  <featureManager>
    <!-- validator-1.0 is a temporary feature needed to enable this functionality -->
    <feature>validator-1.0</feature>
    <feature>jdbc-4.1</feature>
  </featureManager>
  
  <library id="jdbcLib">
    <!-- You must supply a JDBC driver jar -->
    <fileset dir="${server.config.dir}/jdbc" includes="*.jar"/>
  </library>
 
  <dataSource id="DefaultDataSource">
    <jdbcDriver libraryRef="jdbcLib"/>
    <!-- Example properties referencing a in-memory Derby Embeded database -->
    <properties.derby.embedded databaseName="memory:defaultdb" createDatabase="create"/>
  </dataSource>
  
  <httpEndpoint id="defaultHttpEndpoint" httpPort="9080" httpsPort="9443" />
  
  <!-- Simplest security setup to access API discovery with credentials admin/admin -->
  <keyStore id="defaultKeyStore" password="Liberty"/>
  <quickStartSecurity userName="admin" userPassword="admin"/>
</server>

Accessing the API discovery UI

To access the API discovery UI, start your server and you should see the following console output:

$ ./server run defaultServer
Launching defaultServer (WebSphere Application Server 17.0.0.2/wlp-1.0.17.20170303-0602) on IBM J9 VM, version pwa6480sr1-20150417_01 (SR1) (en_US)
[AUDIT ] CWWKE0001I: The server val has been launched.
[AUDIT ] CWWKZ0058I: Monitoring dropins for applications.
[AUDIT ] CWWKF0012I: The server installed the following features: [servlet-3.0, ssl-1.0, jndi-1.0, apiDiscovery-1.0, json-1.0, distributedMap-1.0, jdbc-4.1, validator-1.0].
[AUDIT ] CWWKF0011I: The server val is ready to run a smarter planet.
[AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/ibm/api/explorer/
[AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/ibm/api/
[AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/api/explorer/
[AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/api/docs/

When your server is running, go to the URL https://localhost:9443/ibm/api/explorer/ to access the API discovery UI. Note that the HTTP protocol and port is shown in the server’s console output but we need to be using the secure port (9443) along with the HTTPS protocol in order to access the API discovery UI.

Test a data source connection with API discovery

On the API Discovery page, expand the Validator section to view the test operations:


Between the GET and POST operations, you should be able to mimic any pattern that an application might use to access a database:

  • To test the data source as it sits in your server.xml, you can use the GET or POST operation. This is equivalent to invoking DataSource.getConnection() from an application with no application-specific bindings or resource reference customizations i.e. @Resource(authenticationType = AuthenticationType.CONTAINER)
  • To test a data source with a specific set of credentials, you must use the POST operation. This is equivalent to invoking DataSource.getConnection(String user, String password) from an application.
  • To test a data source with a specific set of auth data (e.g. custom auth data in application bindings) you can use the GET operation to specify which auth data ID should be used to authenticate. Note that if your data source configuration specifies containerAuthData, it is not necessary to use this option.

Click a POST or GET option, depending on what you need to test, to open a form in which you can enter your connection values.

Testing a data source connection using application authentication

One of the most direct ways to test a database connection is by application authentication, invoking DataSource.getConnection(String user, String password) with the credentials that you want to use to authenticate with the database.

To test a database connection using application authentication, use the following options:

  • For the Response Content Type, select application/json.
  • For the uid, type DefaultDataSource.
  • For the auth*, select **application.
  • For the X-Validator-User, type dbuser.
  • For the X-Validator-Password, type the password for that account.

Where DefaultDataSource is the name of your data source, and dbuser is the user name for accessing the database.

Click Try it out!.


If the connection test is successful, the result is displayed with some basic metadata regarding the database and JDBC driver; for example:

{
  "uid": "DefaultDataSource",
  "id": "DefaultDataSource",
  "info": {
    "databaseProductName": "Apache Derby",
    "databaseProductVersion": "10.11.1.1 - (1616546)",
    "jdbcDriverName": "Apache Derby Embedded JDBC Driver",
    "jdbcDriverVersion": "10.11.1.1 - (1616546)",
    "schema": "APP",
    "user": "APP"
  }
}

Example failure scenarios for testing a data source connection

If the data source is not found, the following result is given:

{
  "uid": "DefaultDataSource",
  "failure": {
    "message": "Did not find any configured instances of dataSource matching the request"
  }
}

If the <jdbcDriver> references a library that does not contain any valid DataSource implementation, the following result is given:

{
  "uid": "DefaultDataSource",
  "id": "DefaultDataSource",
  "failure": {
    "class": "java.sql.SQLNonTransientException",
    "message": "DSRA4000E: A valid JDBC driver implementation class was not found for the jdbcDriver dataSource[DefaultDataSource]/jdbcDriver[default-0] using the library jdbcLib. []",
    "stack": [
      "com.ibm.ws.jdbc.internal.JDBCDriverService.classNotFound(JDBCDriverService.java:195)",
      "com.ibm.ws.jdbc.internal.JDBCDriverService.create(JDBCDriverService.java:297)",
      "com.ibm.ws.jdbc.internal.JDBCDriverService.createDefaultDataSource(JDBCDriverService.java:396)",
      // stack trace cut short
      "java.lang.Thread.run(Thread.java:785)"
    ],
    "cause": {
      "class": "java.lang.ClassNotFoundException",
      "message": "org.apache.derby.jdbc.EmbeddedXADataSource40",
      "stack": [
        "com.ibm.ws.classloading.internal.AppClassLoader.findClassCommonLibraryClassLoaders(AppClassLoader.java:499)",
        // stack trace cut short
        "java.lang.Thread.run(Thread.java:785)"
      ]
    }
  }
}

Additional connection testing scenarios

With the new Validator REST API we want you to be able to test your data source connections exactly as your application uses them. Here are the various data source authentication mechanisms that an application might use and how you can exercise them using the validator REST API.

Container Authentication

To test container authentication (i.e. DataSource.getConnection() with a authData element used for authentication), use the GET/POST /ibm/api/validator/dataSource/{uid} API.

For the following server.xml configuration:

<authData id="myAuthData" user="me" password="secret"/>

<dataSource id="myDataSource" containerAuthDataRef="myAuthData">
  <jdbcDriver libraryRef="jdbcLib"/>
  <properties ... />
</dataSource>

Specify the following properties:

  • uid: myDataSource
  • auth: container
  • authAlias: myAuthData
  • X-Validator-User: <unset>
  • X-Validator-Password: <unset>

Application Authentication

To test application authentication (i.e. DataSource.getConnection(userName, password)), use the POST /ibm/api/validator/dataSource/{uid} API.

For the following server.xml configuration:

<dataSource id="myDataSource">
  <jdbcDriver libraryRef="jdbcLib"/>
  <properties ... />
</dataSource>

Specify the following properties:

  • uid: myDataSource
  • auth: application
  • authAlias: <unset>
  • X-Validator-User: me
  • X-Validator-Password: secret

Direct lookup

To test a direct lookup (i.e. new InitialContext().lookup("jdbc/myDataSource") where there is no resource reference bound to jdbc/myDataSource), use the GET/POST /ibm/api/validator/dataSource/{uid} API.

For the following server.xml configuration:

<dataSource id="myDataSource" jndiName="jdbc/myDataSource">
  <jdbcDriver libraryRef="jdbcLib"/>
  <!-- Setting a user and password directly on data source properties is not recommended. -->
  <!-- Instead, you should configure user and password on an authData element             -->
  <properties ... user="me" password="secret"/>
</dataSource>

Specify the following properties:

  • uid: myDataSource
  • auth: <unset>
  • authAlias: <unset>
  • X-Validator-User: <unset>
  • X-Validator-Password: <unset>

Give us feedback!

The configuration validation REST API will be in beta for several months, so please give the feature a try and let us know if you have any ideas for improvement.

Get it now! Ask a question about the beta

Join The Discussion

Your email address will not be published. Required fields are marked *