Skip to content

Commit 9b6a79d

Browse files
Provide complete public API documentation (#26)
This PR improves the Javadocs in the classes that are part of the public API. It aims to provide a complete walkthrough for users reading the Javadocs, guiding them through using the library starting at the package level. This will be visible outside the source code thanks to #24, which provides a direct link to the rendered Javadocs from the `README.md`. This is an attempt to move some of the information which is currently only shown in [code samples](https://github.com/aws-samples/aurora-dsql-samples/blob/c94e23cf6b59d98f444638e6ec1a5132533c76f3/java/pgjdbc_using_dsql_connector/src/main/java/com/amazon/dsql/samples/CustomCredentialsProviderExample.java) into a more maintainable location which is directly tied to the library. I recommend starting the review with the `package-info.java` file since that is the top-level description that will show up in the Javadocs and points to the others. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
1 parent 34ce351 commit 9b6a79d

7 files changed

Lines changed: 534 additions & 23 deletions

File tree

README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,16 @@ Connection conn = DriverManager.getConnection(url);
9191

9292
## Properties
9393

94-
| Parameter | Description | Default |
95-
|-----------|---------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
96-
| `user` | Determines the user for the connection and the token generation method used. Example: `admin` | - |
97-
| `token-duration-secs` | Duration in seconds for token validity | [Same as dsql sdk limit](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/SECTION_authentication-token.html) |
98-
| `profile` | Used for instantiating a `ProfileCredentialsProvider` for token generation with the provided profile name | - |
99-
| `region` | AWS region for Aurora DSQL connections. It is optional. When provided, it will override the region extracted from the URL | - |
100-
| `database` | The database name to connect to | postgres |
94+
The connector supports the following connection properties:
95+
96+
| Parameter | Description | Default |
97+
|-----------|---------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|
98+
| `user` | Determines the user for the connection and the token generation method used. Example: `admin` | - |
99+
| `token-duration-secs` | Duration in seconds for token validity | [Same as AWS SDK default](https://docs.aws.amazon.com/aurora-dsql/latest/userguide/SECTION_authentication-token.html) |
100+
| `profile` | Used for instantiating a `ProfileCredentialsProvider` for token generation with the provided profile name | - |
101+
| `region` | AWS region for Aurora DSQL connections. It is optional. When provided, it will override the region extracted from the URL | - |
102+
103+
**Note:** The database name is specified in the URL path (e.g., `/postgres`). If not specified in the URL, it defaults to `postgres`.
101104

102105
## Logging
103106
Enabling logging is a very useful mechanism for troubleshooting any issue one might potentially experience while using the Aurora DSQL JDBC Connector.

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ tasks.register("generateVersionClass") {
167167
/**
168168
* Version information for Aurora DSQL JDBC Connector.
169169
* Generated automatically during build.
170+
*
171+
* @since 1.1.1
170172
*/
171173
public final class Version {
172174
public static final int MAJOR = $major;

src/main/java/software/amazon/dsql/jdbc/AuroraDsqlCredentialsManager.java

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,72 @@
1919
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
2020
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
2121

22+
/**
23+
* Manages the global AWS credentials provider used for IAM authentication token generation.
24+
*
25+
* <p>This utility class provides a centralized mechanism for configuring the {@link
26+
* AwsCredentialsProvider} used by {@link DSQLConnector} when establishing connections to Aurora
27+
* DSQL. By default, the connector uses the AWS SDK's {@link DefaultCredentialsProvider}, which
28+
* searches for credentials in standard locations. Applications can customize this behavior by
29+
* providing a custom credentials provider through {@link #setProvider(AwsCredentialsProvider)}.
30+
*
31+
* <h3>Default Behavior</h3>
32+
*
33+
* <p>When no custom provider is configured, the connector uses {@link DefaultCredentialsProvider},
34+
* which automatically searches for credentials in the AWS SDK's standard credential chain.
35+
*
36+
* <p>The {@link #resetProvider()} method can be used to restore the default behaviour.
37+
*
38+
* <h3>Custom Profile</h3>
39+
*
40+
* <p>For most use cases requiring a specific AWS profile, use the {@code profile} connection
41+
* property instead of configuring a custom provider through this class. The {@code profile}
42+
* property is simpler and takes precedence over the credentials provider configured here.
43+
*
44+
* <pre>{@code
45+
* Properties props = new Properties();
46+
* props.setProperty("user", "admin");
47+
* props.setProperty("profile", "production");
48+
* Connection conn = DriverManager.getConnection(url, props);
49+
* }</pre>
50+
*
51+
* <h3>Custom Credentials Provider</h3>
52+
*
53+
* <p>For advanced scenarios requiring credential sources beyond named profiles, configure a custom
54+
* provider:
55+
*
56+
* <pre>{@code
57+
* StsClient stsClient = StsClient.builder()
58+
* .region(Region.US_EAST_1)
59+
* .build();
60+
*
61+
* AwsCredentialsProvider assumeRoleCredentials = StsAssumeRoleCredentialsProvider.builder()
62+
* .refreshRequest(
63+
* AssumeRoleRequest.builder()
64+
* .roleArn(ROLE_ARN)
65+
* .roleSessionName("aurora-dsql-session")
66+
* .durationSeconds(3600) // 1 hour
67+
* .build()
68+
* )
69+
* .stsClient(stsClient)
70+
* .build();
71+
*
72+
* AuroraDsqlCredentialsManager.setProvider(assumeRoleCredentials);
73+
*
74+
* Properties props = new Properties();
75+
* props.setProperty("user", "admin");
76+
* Connection conn = DriverManager.getConnection(url, props);
77+
* }</pre>
78+
*
79+
* <h3>Thread Safety</h3>
80+
*
81+
* <p>All methods in this class are thread-safe. The credentials provider can be safely configured
82+
* or retrieved from multiple threads concurrently.
83+
*
84+
* @see DSQLConnector#connect(String, java.util.Properties)
85+
* @see PropertyDefinition#PROFILE
86+
* @since 1.0.0
87+
*/
2288
public final class AuroraDsqlCredentialsManager {
2389

2490
private AuroraDsqlCredentialsManager() {
@@ -30,21 +96,49 @@ private AuroraDsqlCredentialsManager() {
3096
DefaultCredentialsProvider.builder().build();
3197

3298
/**
33-
* Set the AwsCredentialsProvider to use for token generation.
99+
* Configures a custom AWS credentials provider for IAM token generation.
100+
*
101+
* <p>This method sets the global credentials provider used by all subsequent connections that
102+
* do not specify a {@code profile} property. The provider will be used to obtain AWS
103+
* credentials for generating IAM authentication tokens.
34104
*
35-
* @param customCredentialsProvider is an AwsCredentialsProvider (e.g.
36-
* 'ProfileCredentialProvider').
105+
* <p><b>Note:</b> This setting is global and affects all connections created after this method
106+
* is called. Connections that specify a {@code profile} property will use that profile instead
107+
* of this provider.
108+
*
109+
* @param customCredentialsProvider the credentials provider to use for token generation
110+
* @throws NullPointerException if {@code customCredentialsProvider} is null
111+
* @see #resetProvider()
112+
* @see #getProvider()
37113
*/
38114
public static void setProvider(final AwsCredentialsProvider customCredentialsProvider) {
39115
credentialsProvider = customCredentialsProvider;
40116
}
41117

42-
/** Resets AuroraDsqlCredentialsManager back to the DefaultCredentialsProvider. */
118+
/**
119+
* Resets the credentials provider to the default AWS SDK credential chain.
120+
*
121+
* <p>This method restores the credentials provider to {@link DefaultCredentialsProvider},
122+
* reverting any custom provider configured through {@link
123+
* #setProvider(AwsCredentialsProvider)}.
124+
*
125+
* @see #setProvider(AwsCredentialsProvider)
126+
* @see #getProvider()
127+
*/
43128
public static void resetProvider() {
44129
credentialsProvider = DefaultCredentialsProvider.builder().build();
45130
}
46131

47-
/** Retrieves AuroraDsqlCredentialsManager's credentials provider. */
132+
/**
133+
* Retrieves the currently configured AWS credentials provider.
134+
*
135+
* <p>Returns the credentials provider that will be used for IAM token generation when no {@code
136+
* profile} property is specified in the connection.
137+
*
138+
* @return the current credentials provider
139+
* @see #setProvider(AwsCredentialsProvider)
140+
* @see #resetProvider()
141+
*/
48142
public static AwsCredentialsProvider getProvider() {
49143
return credentialsProvider;
50144
}

src/main/java/software/amazon/dsql/jdbc/AuroraDsqlProperty.java

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,63 @@
2121
import javax.annotation.Nonnull;
2222
import javax.annotation.Nullable;
2323

24+
/**
25+
* Represents a connection property for the Aurora DSQL JDBC driver.
26+
*
27+
* <p>This class extends {@link DriverPropertyInfo} to provide additional functionality for managing
28+
* connection properties.
29+
*
30+
* @see DriverPropertyInfo
31+
* @since 1.0.0
32+
*/
2433
public class AuroraDsqlProperty extends DriverPropertyInfo {
2534

35+
/** The default value for this property, or {@code null} if no default is defined. */
2636
public final @Nullable String defaultValue;
2737

38+
/**
39+
* Creates an optional property which accepts any value.
40+
*
41+
* @param name the property name
42+
* @param defaultValue the default value, or {@code null} if no default
43+
* @param description the property description, or {@code null} if no description
44+
*/
2845
public AuroraDsqlProperty(
2946
@Nonnull final String name,
3047
@Nullable final String defaultValue,
31-
final String description) {
48+
@Nullable final String description) {
3249
this(name, defaultValue, description, false);
3350
}
3451

52+
/**
53+
* Creates a property which accepts any value.
54+
*
55+
* @param name the property name
56+
* @param defaultValue the default value, or {@code null} if no default
57+
* @param description the property description, or {@code null} if no description
58+
* @param required whether this property is required for connections
59+
*/
3560
public AuroraDsqlProperty(
3661
@Nonnull final String name,
3762
@Nullable final String defaultValue,
38-
final String description,
63+
@Nullable final String description,
3964
final boolean required) {
4065
this(name, defaultValue, description, required, null);
4166
}
4267

68+
/**
69+
* Creates a property.
70+
*
71+
* @param name the property name
72+
* @param defaultValue the default value, or {@code null} if no default
73+
* @param description the property description, or {@code null} if no description
74+
* @param required whether this property is required for connections
75+
* @param choices valid choices for this property, or {@code null} if any value is allowed
76+
*/
4377
public AuroraDsqlProperty(
4478
@Nonnull final String name,
4579
@Nullable final String defaultValue,
46-
final String description,
80+
@Nullable final String description,
4781
final boolean required,
4882
@Nullable final String[] choices) {
4983
super(name, null);
@@ -53,14 +87,36 @@ public AuroraDsqlProperty(
5387
this.choices = choices;
5488
}
5589

90+
/**
91+
* Retrieves the property value from the given {@link Properties}, or the default value if not
92+
* set.
93+
*
94+
* @param properties the {@link Properties} to query
95+
* @return the property value, or the default value if not set, or {@code null} if neither
96+
* exists
97+
*/
5698
public @Nullable String getOrDefault(Properties properties) {
5799
return properties.getProperty(this.name, this.defaultValue);
58100
}
59101

102+
/**
103+
* Retrieves the property value from the given {@link Properties}.
104+
*
105+
* @param properties the {@link Properties} to query
106+
* @return the property value, or {@code null} if not set
107+
*/
60108
public @Nullable String get(Properties properties) {
61109
return properties.getProperty(this.name);
62110
}
63111

112+
/**
113+
* Sets the property value in the given {@link Properties}.
114+
*
115+
* <p>If the value is {@code null}, the property is removed from the {@link Properties} object.
116+
*
117+
* @param properties the {@link Properties} to modify
118+
* @param value the value to set, or {@code null} to remove the property
119+
*/
64120
public void set(Properties properties, @Nullable String value) {
65121
if (value == null) {
66122
properties.remove(name);
@@ -69,14 +125,35 @@ public void set(Properties properties, @Nullable String value) {
69125
}
70126
}
71127

128+
/**
129+
* Retrieves the property value as an integer.
130+
*
131+
* <p>If the property is not set and no default value exists, returns {@code 0}.
132+
*
133+
* @param properties the {@link Properties} to query
134+
* @return the property value as an integer, or {@code 0} if not set and no default exists
135+
* @throws NumberFormatException if the property value cannot be parsed as an integer
136+
*/
72137
public int getInteger(final Properties properties) {
73138
final Object value = properties.get(name);
139+
if (value == null && defaultValue == null) {
140+
return 0;
141+
}
74142
if (value instanceof Integer) {
75143
return (Integer) value;
76144
}
77145
return Integer.parseInt(properties.getProperty(name, defaultValue));
78146
}
79147

148+
/**
149+
* Retrieves the property value as a long.
150+
*
151+
* <p>If the property is not set and no default value exists, returns {@code 0L}.
152+
*
153+
* @param properties the {@link Properties} to query
154+
* @return the property value as a long, or {@code 0L} if not set and no default exists
155+
* @throws NumberFormatException if the property value cannot be parsed as a long
156+
*/
80157
public long getLong(final Properties properties) {
81158
final Object value = properties.get(name);
82159
if (value == null && defaultValue == null) {
@@ -88,6 +165,17 @@ public long getLong(final Properties properties) {
88165
return Long.parseLong(properties.getProperty(name, defaultValue));
89166
}
90167

168+
/**
169+
* Converts this property to a {@link DriverPropertyInfo} instance.
170+
*
171+
* <p>Creates a {@link DriverPropertyInfo} object containing this property's metadata (name,
172+
* description, etc.) along with the current value from the provided {@link Properties} object.
173+
* If the property is not set in the {@link Properties} object, the value will be {@code null}.
174+
*
175+
* @param properties the {@link Properties} to query for the current value
176+
* @return a {@link DriverPropertyInfo} instance with property metadata and provided property
177+
* value
178+
*/
91179
public DriverPropertyInfo toDriverPropertyInfo(final Properties properties) {
92180
final DriverPropertyInfo propertyInfo = new DriverPropertyInfo(name, get(properties));
93181
propertyInfo.required = required;

0 commit comments

Comments
 (0)