Skip to content

Commit d32e99e

Browse files
committed
Restructure examples with alternatives folder structure
1 parent 99d173b commit d32e99e

61 files changed

Lines changed: 1653 additions & 440 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/java-pgjdbc-hikaricp-integ-tests.yml

Lines changed: 0 additions & 61 deletions
This file was deleted.

.github/workflows/python-psycopg2-integ-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ jobs:
6868
pip list
6969
echo "$GITHUB_WORKSPACE" >> $GITHUB_PATH
7070
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem
71-
python src/example.py
71+
python src/example_preferred.py

.github/workflows/python-psycopg3-integ-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,5 @@ jobs:
6868
pip list
6969
echo "$GITHUB_WORKSPACE" >> $GITHUB_PATH
7070
wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem
71-
python src/example.py
71+
python src/example_preferred.py
7272

java/pgjdbc/pom.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,36 @@
1111
<properties>
1212
<maven.compiler.release>17</maven.compiler.release>
1313
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14-
<mainClass>org.example.Example</mainClass>
14+
<mainClass>org.example.ExamplePreferred</mainClass>
1515
<connector.version>1.2.0</connector.version>
16+
<hikaricp.version>5.1.0</hikaricp.version>
17+
<aws.sdk.version>2.31.32</aws.sdk.version>
1618
<junit.version>5.10.0</junit.version>
1719
<trimStackTrace>false</trimStackTrace>
1820
</properties>
1921

2022
<dependencies>
23+
<dependency>
24+
<groupId>com.zaxxer</groupId>
25+
<artifactId>HikariCP</artifactId>
26+
<version>${hikaricp.version}</version>
27+
</dependency>
2128
<dependency>
2229
<groupId>software.amazon.dsql</groupId>
2330
<artifactId>aurora-dsql-jdbc-connector</artifactId>
2431
<version>${connector.version}</version>
2532
</dependency>
33+
<!-- AWS SDK dependencies for SDK-only example (ExampleWithNoConnector) -->
34+
<dependency>
35+
<groupId>software.amazon.awssdk</groupId>
36+
<artifactId>dsql</artifactId>
37+
<version>${aws.sdk.version}</version>
38+
</dependency>
39+
<dependency>
40+
<groupId>org.postgresql</groupId>
41+
<artifactId>postgresql</artifactId>
42+
<version>42.7.7</version>
43+
</dependency>
2644
<dependency>
2745
<groupId>org.junit.jupiter</groupId>
2846
<artifactId>junit-jupiter</artifactId>

java/pgjdbc_hikaricp/src/main/java/org/example/Example.java renamed to java/pgjdbc/src/main/java/org/example/ExamplePreferred.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
* <li>Production-ready configuration with connection validation</li>
2222
* </ul>
2323
*/
24-
public class Example {
24+
public class ExamplePreferred {
2525

2626
private final HikariDataSource dataSource;
2727

28-
public Example(String endpoint, String user) {
28+
public ExamplePreferred(String endpoint, String user) {
2929
this.dataSource = initializeConnectionPool(endpoint, user);
3030
}
3131

@@ -122,7 +122,7 @@ public static void main(String[] args) throws SQLException {
122122
assert clusterUser != null : "CLUSTER_USER environment variable is not set";
123123

124124
System.out.println("Initializing Aurora DSQL example...");
125-
Example example = new Example(clusterEndpoint, clusterUser);
125+
ExamplePreferred example = new ExamplePreferred(clusterEndpoint, clusterUser);
126126
System.out.println("Example initialized!");
127127
System.out.println();
128128

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Alternative Examples
2+
3+
The recommended approach is `ExamplePreferred.java` in the parent directory, which uses HikariCP connection pool with the Aurora DSQL JDBC Connector.
4+
5+
## Why Connection Pooling with the Connector?
6+
7+
Aurora DSQL has specific connection characteristics:
8+
- **60-minute max connection lifetime** - connections are terminated after 1 hour
9+
- **15-minute token expiry** - IAM auth tokens must be refreshed
10+
- **Optimized for concurrency** - more concurrent connections with smaller batches yields better throughput
11+
12+
The connector + pool combination handles this automatically:
13+
- Generates fresh IAM tokens per connection
14+
- Recycles connections before the 60-minute limit (via `maxLifetime < 3600000`)
15+
- Reuses warmed connections for better performance
16+
17+
## Alternatives
18+
19+
### `no_connection_pool/`
20+
Examples without pooling:
21+
- `ExampleWithNoConnectionPool.java` - Single connection with connector
22+
- `ExampleWithNoConnector.java` - SDK-only, for environments where the connector cannot be used (requires manual token management)

java/pgjdbc/src/main/java/org/example/Example.java renamed to java/pgjdbc/src/main/java/org/example/alternatives/no_connection_pool/ExampleWithNoConnectionPool.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.example;
1+
package org.example.alternatives.no_connection_pool;
22

33

44
import java.sql.Connection;
@@ -8,7 +8,7 @@
88
import java.sql.Statement;
99
import java.util.Properties;
1010

11-
public class Example {
11+
public class ExampleWithNoConnectionPool {
1212

1313
// Get a connection to Aurora DSQL.
1414
public static Connection getConnection(String endpoint, String user) throws SQLException {
@@ -33,7 +33,7 @@ public static void main(String[] args) throws SQLException {
3333
String clusterUser = System.getenv("CLUSTER_USER");
3434
assert clusterUser != null : "CLUSTER_USER environment variable is not set";
3535

36-
try (Connection conn = Example.getConnection(clusterEndpoint, clusterUser)) {
36+
try (Connection conn = ExampleWithNoConnectionPool.getConnection(clusterEndpoint, clusterUser)) {
3737
if (!clusterUser.equals("admin")) {
3838
Statement setSchema = conn.createStatement();
3939
setSchema.execute("SET search_path=myschema");
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.example.alternatives.no_connection_pool;
2+
3+
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
4+
import software.amazon.awssdk.services.dsql.DsqlUtilities;
5+
import software.amazon.awssdk.services.dsql.model.GenerateAuthTokenRequest;
6+
import software.amazon.awssdk.regions.Region;
7+
8+
import java.sql.Connection;
9+
import java.sql.DriverManager;
10+
import java.sql.ResultSet;
11+
import java.sql.SQLException;
12+
import java.sql.Statement;
13+
import java.util.Properties;
14+
15+
public class ExampleWithNoConnector {
16+
17+
// Get a connection to Aurora DSQL.
18+
public static Connection getConnection(String endpoint, String user, String region) throws SQLException {
19+
DsqlUtilities utilities = DsqlUtilities.builder()
20+
.region(Region.of(region))
21+
.credentialsProvider(DefaultCredentialsProvider.create())
22+
.build();
23+
24+
// The token expiration time is optional, and the default value is 900 seconds
25+
GenerateAuthTokenRequest tokenGenerator = GenerateAuthTokenRequest.builder()
26+
.hostname(endpoint)
27+
.region(Region.of(region))
28+
.build();
29+
30+
// Generate a fresh password token for each connection, to ensure the token is
31+
// not expired when the connection is established
32+
String password;
33+
if (user.equals("admin")) {
34+
password = utilities.generateDbConnectAdminAuthToken(tokenGenerator);
35+
} else {
36+
password = utilities.generateDbConnectAuthToken(tokenGenerator);
37+
}
38+
39+
Properties props = new Properties();
40+
props.setProperty("user", user);
41+
props.setProperty("password", password);
42+
// Use the DefaultJavaSSLFactory so that Java's default trust store can be used
43+
// to verify the server's root cert.
44+
props.setProperty("sslmode", "verify-full");
45+
props.setProperty("sslfactory", "org.postgresql.ssl.DefaultJavaSSLFactory");
46+
props.setProperty("sslNegotiation", "direct");
47+
48+
String url = "jdbc:postgresql://" + endpoint + ":5432/postgres";
49+
50+
return DriverManager.getConnection(url, props);
51+
}
52+
53+
public static void main(String[] args) throws SQLException {
54+
String clusterEndpoint = System.getenv("CLUSTER_ENDPOINT");
55+
assert clusterEndpoint != null : "CLUSTER_ENDPOINT environment variable is not set";
56+
57+
String clusterUser = System.getenv("CLUSTER_USER");
58+
assert clusterUser != null : "CLUSTER_USER environment variable is not set";
59+
60+
String region = System.getenv("REGION");
61+
assert region != null : "REGION environment variable is not set";
62+
63+
try (Connection conn = ExampleWithNoConnector.getConnection(clusterEndpoint, clusterUser, region)) {
64+
if (!clusterUser.equals("admin")) {
65+
Statement setSchema = conn.createStatement();
66+
setSchema.execute("SET search_path=myschema");
67+
setSchema.close();
68+
}
69+
// Create a new table named owner
70+
Statement create = conn.createStatement();
71+
create.executeUpdate("""
72+
CREATE TABLE IF NOT EXISTS owner(
73+
id uuid NOT NULL DEFAULT gen_random_uuid(),
74+
name varchar(30) NOT NULL,
75+
city varchar(80) NOT NULL,
76+
telephone varchar(20) DEFAULT NULL,
77+
PRIMARY KEY (id))""");
78+
create.close();
79+
80+
// Insert some data
81+
Statement insert = conn.createStatement();
82+
insert.executeUpdate(
83+
"INSERT INTO owner (name, city, telephone) VALUES ('John Doe', 'Anytown', '555-555-1999')");
84+
insert.close();
85+
86+
// Read back the data and assert they are present
87+
String selectSQL = "SELECT * FROM owner";
88+
Statement read = conn.createStatement();
89+
ResultSet rs = read.executeQuery(selectSQL);
90+
while (rs.next()) {
91+
assert rs.getString("id") != null;
92+
assert rs.getString("name").equals("John Doe");
93+
assert rs.getString("city").equals("Anytown");
94+
assert rs.getString("telephone").equals("555-555-1999");
95+
}
96+
97+
// Delete some data
98+
String deleteSql = String.format("DELETE FROM owner where name='John Doe'");
99+
Statement delete = conn.createStatement();
100+
delete.executeUpdate(deleteSql);
101+
delete.close();
102+
}
103+
System.out.println("Connection exercised successfully");
104+
}
105+
}

java/pgjdbc/src/test/java/org/example/DsqlExampleTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public class DsqlExampleTest {
88
@Test
9-
public void testExample() {
10-
assertAll(() -> Example.main(new String[]{}));
9+
public void testExamplePreferred() {
10+
assertAll(() -> ExamplePreferred.main(new String[]{}));
1111
}
1212
}

0 commit comments

Comments
 (0)