Introduction
In the part 1 of our series, we learned the concepts behind the Amazon AuroraDSQL and explored how to create a single-region PostgreSQL-compatible DSQL cluster and connect to it using the sample application for creating and retrieving order and order items which uses API Gateway and Lambda with the managed Java 21 runtime.
The only one compile-time dependency to DSQL on our sample application was the dependency to the software.amazon.awssdk.services.dsql.DsqlUtilities class in the DsqlDataSourceConfig.java. The reason we required this dependency was to build the instance of DsqlUtilities to then generate database connect admin authentication token (DsqlUtilities.generateDbConnectAdminAuthToken()), see the implementation of the getAuthTokenForAdminUser() in the DsqlDataSourceConfig.java. We required this token to set it as connection password in 2 places in the DsqlDataSourceConfig.java:
- When we built HikariDataSource
private static HikariDataSource hds; static { final HikariConfig config = new HikariConfig(); config.setUsername("admin"); config.setJdbcUrl(JDBC_URL); config.setMaxLifetime(1500 * 1000); // pool connection expiration time in milliseconds, default 30 config.setMaximumPoolSize(1); // default is 10 String authToken = getAuthTokenForAdminUser(); config.setPassword(authToken); hds = new HikariDataSource(config); }
- Each time when we wanted to execute SQL statement and needed to get the database connection from the HikariDataSource
public static Connection getPooledConnection() throws SQLException { String authToken = getAuthTokenForAdminUser(); hds.setPassword(authToken); return hds.getConnection(); }
Please read the brilliant article Aurora DSQL: How authentication and authorization works by Marc Bowes in order to understand how connections to Aurora DSQL are authenticated and authorized.
We see already that the user experience is not great as we created some repetitive code. In order to improve that AWS released Aurora DSQL JDBC Connector.
Aurora DSQL JDBC Connector
The main idea behind the Aurora DSQL JDBC Connector is to add an authentication layer on top of the PostgreSQL JDBC driver that handles IAM token generation, allowing users to connect to Aurora DSQL without changing their existing JDBC workflows.
Although Aurora DSQL provides a PostgreSQL-compatible interface, existing PostgreSQL drivers do not currently support Aurora DSQL's IAM authentication requirements. The Aurora DSQL JDBC Connector allows customers to continue using their existing PostgreSQL workflows while enabling IAM authentication through:
- Automatic Token Generation: IAM tokens are generated automatically using AWS credentials
- Seamless Integration: Works with existing JDBC connection patterns
- AWS Credentials Support: Supports various AWS credential providers (default, profile-based, etc.)
- The Aurora DSQL JDBC Connector works with connection pooling libraries such as HikariCP. The connector handles IAM token generation during connection establishment, allowing connection pools to operate normally.
Let's see how it works. For it a published a re-worked version of the sample application. Let's explore the differences:
In the pom.xml we nee to import the following dependency:
<dependency> <groupId>software.amazon.dsql</groupId> <artifactId>aurora-dsql-jdbc-connector</artifactId> <version>1.0.0</version> </dependency>
All other difference are in the DsqlDataSourceConfig.java:
- JDBC URL is built like this:
private static final String AURORA_DSQL_CLUSTER_ENDPOINT = System.getenv("AURORA_DSQL_CLUSTER_ENDPOINT"); private static final String JDBC_URL = "jdbc:aws-dsql:postgresql://" + AURORA_DSQL_CLUSTER_ENDPOINT + ":5432/postgres?sslmode=verify-full&sslfactory=org.postgresql.ssl.DefaultJavaSSLFactory" + "&token-duration-secs=900";
We use jdbc:aws-dsql:postgresql as URL format for connecting to Aurora DSQL clusters and attached token-duration-secs=900 url parameter to define the token duration.
- We don't need to generate the authentication token and set it as password as this will be handeled by Aurora DSQL JDBC Connector for us, which simplifies the code to create the HikariDataSource and get the database connection from it:
private static HikariDataSource hds; static { final HikariConfig config = new HikariConfig(); config.setUsername("admin"); config.setJdbcUrl(JDBC_URL); config.setMaxLifetime(1500 * 1000); // pool connection expiration time in milliseconds, default 30 config.setMaximumPoolSize(1); // default is 10 }
and
public static Connection getPooledConnection() throws SQLException { return hds.getConnection(); }
That's why we also don't need to create the instance of DsqlUtilities and don't need any compile-time dependency to the DSQL libraries, so our code looks like as pure JDBC implementation. Of course, we have a runtime-time dependency to Aurora DSQL JDBC Connector and we use jdbc:aws-dsql:postgresql as URL format so that this connector as JDBC driver implementation can take over.
That's it. We don't need any more changes.
Conclusion
In this part of the series, we explained how easy it to modify the code to use Aurora DSQL JDBC Connector and clearly observed its benefits like code simplification and better user experience. Give it a try!
Top comments (0)