Menu Search

Appendix C. JMS Extensions

This section illustrates using Qpid specific extensions to JMS for the management of connections, queues, exchanges and bindings.

Important

It is not recommended that these extensions are generally used. These interfaces are subject to change and will not be supported in this form for AMQP 1.0. Instead, the reader is directed towards the Managment interfaces of the Broker.

C.1. Connection extensions

Connection extensions allows overriding connection configurations like username or password in response to some environment changes like account rotation or authentication token expiration.

The extensions take the form of a BiFunction<Connection, URI, Object> passed into the ConnectionFactory using the AMQConnectionFactory#setExtension(String, BiFunction) or PooledConnectionFactory#setExtension(String, BiFunction).

A table below lists supported extensions.

Table C.1. Connection Extensions

Extension NameDescription
username

Allows to hook a custom code for provisioning of user name which would be used in authentication with a remote host.

password

Allows to hook a custom code for provisioning of user password which would be used in authentication with a remote host.


The following example illustrates how expired OAUTH2 authentication token can be recreated.

Example C.1. Inject password extension

final String connectionURL = "...";                                                                    1
final TokenGenerator tokenGenerator = new TokenGenerator(...);                                         2

final BiFunction<Connection, URI, Object> tokenExtension = new BiFunction<Connection, URI, Object>()   3
{
    private volatile String token;
    private long currentTokenExpirationTime;

    @Override
    public Object apply(final Connection connection, final URI uri)
    {
        long currentTime = System.currentTimeMillis();
        if (currentTime > currentTokenExpirationTime)                                                  4
        {
            this.token = tokenGenerator.generateAccessToken();                                         5
            this.currentTokenExpirationTime = tokenGenerator.getTokenExpirationTime(token);            6
        }
        return this.token;
    }
};
final AMQConnectionFactory factory = new AMQConnectionFactory(connectionURL);                          7
factory.setExtension(ConnectionExtension.PASSWORD_OVERRIDE.name(), tokenExtension);                    8

final Connection connection = factory.createConnection();                                              9
          

1

Connection URL

2

Helper object to generate access token for a specific OAUTH2 implementation

3

Password extension for token renewal

4

Check token expiration

5

Get new token

6

Preserve token expiration time

7

Create connection factory

8

Register password extension for token regeneration

9

Open connection

In the snippet above an implementation of BiFunction<Connection, URI, Object> is created at (3) for access token provisioning. The function implementation checks the token expiration at (4) and regenerate the token at (5) using a helper object (2) implementing calls to OAUTH2 specific API. The token expiration time is preserved at (6) for the following reconnects attempts. An instance of AMQConnectionFactory is created at (7) for a given connection URL (1). A password extension is registered at (8). JMS connection is open at (9). The example uses a hypothetical class TokenGenerator invoking underlying OAUTH2 API to generate/renew access token and get token expiration time.

Connection Extensions can be used together with ConnectAttemptListener to change credentials on connectivity failures. Please check Section C.2, “ConnectAttemptListener” for more details.