### Configuration Example 1: Writer Connection Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheGdbFailoverPlugin.md Configure the driver to provide a writer connection for an application deployed in `us-west-1` connecting to a Global Database with multiple regions. This setup prioritizes writer connections. ```properties failoverHomeRegion=us-west-1 activeHomeFailoverMode=strict-writer inactiveHomeFailoverMode=strict-writer globalClusterInstanceHostPatterns=?.XYZ1.us-east-1.rds.amazonaws.com,?.XYZ2.us-east-2.rds.amazonaws.com,?.XYZ3.us-west-1.rds.amazonaws.com wrapperDialect=global-aurora-mysql wrapperPlugins=initialConnection,gdbFailover,efm2 ``` -------------------------------- ### Set up Vert.x Start Method Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/VertxExample/README.md Configure the Vert.x server and connection pools within the start method. Ensure proper handling of server startup success or failure. ```java @Override public void start(Promise startPromise) throws Exception { Router router = Router.router(vertx); router.get("/id").handler(this::getCurrentInstance); write = JDBCPool.pool(vertx, writeConfig); read = JDBCPool.pool(vertx, readConfig); vertx.createHttpServer() .requestHandler(router) .listen(8888, http -> { if (http.succeeded()) { try { startPromise.complete(); System.out.println("HTTP server started on port 8888"); } catch (IllegalStateException e) { startPromise.fail(http.cause()); } } }); } ``` -------------------------------- ### Example: ConnectionPluginFactory Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/LoadablePlugins.md A `ConnectionPluginFactory` implementation is necessary for registering and initializing custom plugins. This example shows a basic factory structure. ```java public class ExecutionTimeConnectionPluginFactory implements ConnectionPluginFactory { // ... implementation ... } ``` -------------------------------- ### Example: ExecutionTimeConnectionPlugin Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/LoadablePlugins.md This plugin overrides only the `execute` method to measure elapsed time during query execution, without affecting connection setup. ```java public class ExecutionTimeConnectionPlugin extends AbstractConnectionPlugin { // ... only overrides execute method ... } ``` -------------------------------- ### Configuration Example 2: Reader Connection with Region Priority Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheGdbFailoverPlugin.md Configure the driver to provide reader connections in `us-west-1` for an application deployed in the same region. This setup prioritizes reader connections from the `us-west-1` region, even after a GDB primary region switch. ```properties failoverHomeRegion=us-west-1 activeHomeFailoverMode=strict-home-reader inactiveHomeFailoverMode=strict-home-reader globalClusterInstanceHostPatterns=?.XYZ1.us-east-1.rds.amazonaws.com,?.XYZ2.us-east-2.rds.amazonaws.com,?.XYZ3.us-west-1.rds.amazonaws.com wrapperDialect=global-aurora-mysql wrapperPlugins=initialConnection,gdbFailover,efm2 ``` -------------------------------- ### Setup PostgreSQL Database Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/EncryptSpring/README.md Create the PostgreSQL database. The application will automatically set up the necessary extensions, types, and functions for encryption. ```bash createdb mydb ``` -------------------------------- ### Set up Vert.x Router and Route Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/VertxExample/README.md Initializes a Vert.x router and defines a GET route for '/id' that will be handled by the `getCurrentInstance` method. ```java Router router = Router.router(vertx); router.get("/id").handler(this::getCurrentInstance); ``` -------------------------------- ### Example Data Model Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringTxFailoverExample/README.md Represents an 'Example' object with an ID and status. Used for database interactions. ```java package example; public class Example { private int id; private int status; public Example() { super(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getStatus() { return status; } public void setStatus(int name) { this.status = name; } @Override public String toString() { return String.format("Example [id=%s, status=%s]", id, status); } } ``` -------------------------------- ### Good Plugin Implementation Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/development-guide/LoadablePlugins Illustrates recommended practices for custom plugin development, such as retrieving shared information when needed and using pipeline lambdas for operations like connecting. ```java public class GoodExample extends AbstractConnectionPlugin { PluginService pluginService; HostListProvider hostListProvider; Properties props; GoodExample(PluginService pluginService, Properties props) { this.pluginService = pluginService; this.props = props; } @Override public Set getSubscribedMethods() { return new HashSet<>(Collections.singletonList("*")); } @Override public T execute( final Class resultClass, final Class exceptionClass, final Object methodInvokeOn, final String methodName, final JdbcCallable jdbcMethodFunc, final Object[] jdbcMethodArgs) throws E { if (this.pluginService.getHosts().isEmpty()) { // Re-fetch host information if it is empty. this.pluginService.forceRefreshHostList(); } return jdbcMethodFunc.call(); } @Override public Connection connect(String driverProtocol, HostSpec hostSpec, Properties props, boolean isInitialConnection, JdbcCallable connectFunc) throws SQLException { if (PropertyDefinition.USER.getString(props) == null) { PropertyDefinition.TARGET_DRIVER_USER_PROPERTY_NAME.set(props, "defaultUser"); } // Call the pipeline lambda to connect. return connectFunc.call(); } } ``` -------------------------------- ### Valid SQL Annotation Examples Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheKmsEncryptionPlugin.md Illustrates correct syntax for SQL comment annotations used to mark parameters for encryption. These examples show the required format `/*@encrypt:table.column*/` preceding the parameter placeholder. ```sql /*@encrypt:users.ssn*/ ? ``` ```sql /*@encrypt:customers.credit_card*/ ? ``` ```sql /*@encrypt:orders.payment_info*/ ? ``` -------------------------------- ### Example: IamAuthConnectionPlugin Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/LoadablePlugins.md This plugin overrides only the `connect` method, focusing solely on establishing database connections using IAM credentials. ```java public class IamAuthConnectionPlugin extends AbstractConnectionPlugin { // ... only overrides connect method ... } ``` -------------------------------- ### Switchover Summary Log Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheBlueGreenPlugin.md This log entry displays a detailed summary of a Blue/Green switchover, including timestamps and phase offsets. It requires setting the log level to FINE for the BlueGreenStatusProvider class. ```log [2025-11-14 15:59:52.084] [INFO ] [pool-2-thread-1] [software.amazon.jdbc.plugin.bluegreen.BlueGreenStatusProvider logSwitchoverFinalSummary] : [bgdId: '1'] --------------------------------------------------------------------------------------- timestamp time offset (ms) event --------------------------------------------------------------------------------------- 2025-11-14T23:58:18.519Z -28178 ms NOT_CREATED 2025-11-14T23:58:19.172Z -27525 ms CREATED 2025-11-14T23:58:39.279Z -7418 ms PREPARATION 2025-11-14T23:58:46.697Z 0 ms Monitors reset - start 2025-11-14T23:58:46.697Z 0 ms IN_PROGRESS 2025-11-14T23:58:49.788Z 3090 ms POST 2025-11-14T23:59:03.373Z 16675 ms Green topology changed 2025-11-14T23:59:03.374Z 16677 ms Monitors reset - green topology 2025-11-14T23:59:19.815Z 33117 ms Blue DNS updated 2025-11-14T23:59:52.081Z 65383 ms Green DNS removed 2025-11-14T23:59:52.082Z 65384 ms COMPLETED --------------------------------------------------------------------------------------- ``` -------------------------------- ### Read-Write Method Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringHibernateBalancedReaderOneDataSourceExample/CUSTOM_ANNOTATIONS.md This example shows a read-write transactional method that automatically routes its database operations to the writer instance. It includes retry logic for failover and transaction system exceptions. ```java @Retryable(value = {ShouldRetryTransactionException.class, TransactionSystemException.class}, maxAttempts = 3) @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateBookAvailabilityTransactional() { // Automatically routed to writer instance final List allBooks = this.repository.findAll(); for (Book book : allBooks) { book.setQuantityAvailable(book.getQuantityAvailable() + 1); } this.repository.saveAll(allBooks); } ``` -------------------------------- ### Configure Blue/Green Deployment Plugin Source: https://context7.com/aws/aws-advanced-jdbc-wrapper/llms.txt Set up the `bg` plugin for seamless Blue/Green deployments. Configure monitoring intervals and timeouts for connections and switchovers. Ensure the `rds_tools` extension is installed for PostgreSQL. ```java import java.sql.*; import java.util.Properties; public class BlueGreenExample { public static void main(String[] args) throws SQLException { final Properties props = new Properties(); props.setProperty("user", "db_user"); props.setProperty("password", "db_password"); props.setProperty("wrapperPlugins", "bg,failover2,efm2"); // Required for RDS PostgreSQL: ensure rds_tools extension is installed: // CREATE EXTENSION rds_tools; // Unique ID per Blue/Green Deployment (required when using multiple BGDs) props.setProperty("bgdId", "my-bgd-1"); // Monitoring intervals props.setProperty("bgBaselineMs", "60000"); // normal polling: 1 minute props.setProperty("bgIncreasedMs", "1000"); // increased polling: 1s during switchover props.setProperty("bgHighMs", "100"); // high-freq: 100ms during active switchover // Max switchover duration before driver assumes completion props.setProperty("bgSwitchoverTimeoutMs", "180000"); // Separate timeouts for Blue/Green monitoring connections props.setProperty("blue-green-monitoring-connectTimeout", "10000"); props.setProperty("blue-green-monitoring-socketTimeout", "10000"); String url = "jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/mydb"; try (Connection conn = DriverManager.getConnection(url, props); Statement stmt = conn.createStatement()) { stmt.executeUpdate("UPDATE config SET value = 'active' WHERE key = 'status'"); System.out.println("Write succeeded; Blue/Green plugin will handle switchover transparently."); } } } ``` -------------------------------- ### ConnectionStringHostListProvider Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/Pipelines.md A simple host list provider that parses host and port information directly from the connection string during initialization. It does not perform additional work or re-fetching of information. ```java ConnectionStringHostListProvider ``` -------------------------------- ### Run Unit Tests on macOS Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/development-guide/DevelopmentGuide Execute the Gradle wrapper to run unit tests on macOS. This also validates your environment setup. ```bash ./gradlew test ``` -------------------------------- ### Subscribe to Pipelines Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/LoadablePlugins.md Plugins can subscribe to specific pipelines to intercept events during different stages of the connection lifecycle. This example shows subscriptions to the host provider and connect pipelines. ```java public Set getSubscribedMethods() { return new HashSet<>(Arrays.asList( "initHostProvider", "connect", "notifyConnectionChanged", "notifyNodeListChanged" )); } ``` -------------------------------- ### Install pgcrypto Extension (PostgreSQL) Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/DatabaseEncryptionSetup.md Installs the pgcrypto extension, which is required for HMAC verification functions in PostgreSQL. This step is not needed for MySQL. ```sql CREATE EXTENSION IF NOT EXISTS pgcrypto; ``` -------------------------------- ### Install Encrypted Data Type (PostgreSQL) Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/DatabaseEncryptionSetup.md Installs a custom 'encrypted_data' DOMAIN type in PostgreSQL for minimum length validation. This is not applicable to MySQL. ```java import software.amazon.jdbc.plugin.encryption.schema.EncryptedDataTypeInstaller; Connection conn = DriverManager.getConnection(url, props); EncryptedDataTypeInstaller.installEncryptedDataType(conn, "encrypt"); ``` -------------------------------- ### Create and Set a Configuration Profile Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/UsingTheJdbcDriver.md Use ConfigurationProfileBuilder to create a new profile with specified plugins and then set it using wrapperProfileName. This avoids needing to specify plugins via the wrapperPlugins parameter. ```java ConfigurationProfileBuilder.get() .withName("testProfile") .withPluginFactories(Arrays.asList( FailoverConnectionPluginFactory.class, HostMonitoringConnectionPluginFactory.class, CustomConnectionPluginFactory.class)) .buildAndSet(); properties.setProperty("wrapperProfileName", "testProfile"); ``` -------------------------------- ### Install Encrypted Data Type (PostgreSQL) Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/KmsEncryptionPluginGuide.md Installs the custom 'encrypted_data' domain type and associated validation functions in PostgreSQL using the EncryptedDataTypeInstaller class. ```java import software.amazon.jdbc.plugin.encryption.schema.EncryptedDataTypeInstaller; // Install the encrypted_data type and validation functions EncryptedDataTypeInstaller.installEncryptedDataType(connection, "encrypt"); ``` -------------------------------- ### Create and Set a Configuration Profile Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/using-the-jdbc-driver/UsingTheJdbcDriver Use this to create a custom configuration profile for loading specific plugins. Set the 'wrapperProfileName' connection property to the name of the created profile. ```java properties.setProperty("wrapperProfileName", "testProfile"); DriverConfigurationProfiles.addOrReplaceProfile( "testProfile", Arrays.asList( FailoverConnectionPluginFactory.class, HostMonitoringConnectionPluginFactory.class, CustomConnectionPluginFactory.class)); ``` -------------------------------- ### Read-Only Method Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringHibernateBalancedReaderOneDataSourceExample/CUSTOM_ANNOTATIONS.md This example demonstrates a read-only transactional method that automatically routes its database operations to a reader instance. It includes retry logic for failover resilience. ```java @Retryable(value = { ShouldRetryTransactionException.class }, maxAttempts = 3) @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) public int getNumOfBooksTransactional() { // Automatically routed to reader instance return this.repository.findAll().stream().mapToInt(Book::getQuantityAvailable).sum(); } ``` -------------------------------- ### Use Configuration Profiles and Presets Source: https://context7.com/aws/aws-advanced-jdbc-wrapper/llms.txt Leverage built-in configuration presets or create custom profiles for optimized plugin combinations. Presets like 'A2' offer pre-tuned settings for specific scenarios. ```java import java.sql.*; import java.util.Properties; import software.amazon.jdbc.profile.ConfigurationProfileBuilder; import software.amazon.jdbc.plugin.failover.FailoverConnectionPluginFactory; import software.amazon.jdbc.plugin.efm.HostMonitoringConnectionPluginFactory; public class ConfigurationProfileExample { public static void main(String[] args) throws SQLException { final Properties props = new Properties(); props.setProperty("user", "db_user"); props.setProperty("password", "db_password"); // Option 1: Use a built-in preset // Presets: A0-A2 (no pool), D0-D2 (internal pool), G0-G2 (external pool) // SF_ prefix variants for Spring Framework props.setProperty("wrapperProfileName", "A2"); // Option 2: Create a custom profile based on a built-in preset ConfigurationProfileBuilder.from("A2") .withName("myProfile") // .withDialect(new CustomDatabaseDialect()) .buildAndSet(); // props.setProperty("wrapperProfileName", "myProfile"); // Option 3: Build a profile from scratch with specific plugin factories ConfigurationProfileBuilder.get() .withName("customProfile") .withPluginFactories(java.util.Arrays.asList( FailoverConnectionPluginFactory.class, HostMonitoringConnectionPluginFactory.class )) .buildAndSet(); // props.setProperty("wrapperProfileName", "customProfile"); String url = "jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/mydb"; try (Connection conn = DriverManager.getConnection(url, props)) { System.out.println("Connected using preset: " + props.getProperty("wrapperProfileName")); } } } ``` -------------------------------- ### Bad Plugin Implementation Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/development-guide/LoadablePlugins Demonstrates bad practices in custom plugin development, including keeping local copies of shared information, using driver-specific objects, and making direct connections instead of using pipeline lambdas. ```java public class BadPlugin extends AbstractConnectionPlugin { PluginService pluginService; HostListProvider hostListProvider; Properties props; BadPlugin(PluginService pluginService, Properties props) { this.pluginService = pluginService; this.props = props; // Bad Practice #1: keeping local copies of items // Plugins should not keep local copies of the host list provider, the topology or the connection. // Host list provider is kept in the Plugin Service and can be modified by other plugins, // therefore it should be retrieved by calling pluginService.getHostListProvider() when it is needed. this.hostListProvider = this.pluginService.getHostListProvider(); } @Override public Set getSubscribedMethods() { return new HashSet<>(Collections.singletonList("*")); } @Override public Connection connect(String driverProtocol, HostSpec hostSpec, Properties props, boolean isInitialConnection, JdbcCallable connectFunc) throws SQLException { // Bad Practice #2: using driver-specific objects. // Not all drivers support the same configuration parameters. For instance, while MySQL Connector/J Supports "database", // PGJDBC uses "dbname" for database names. if (props.getProperty("database") == null) { props.setProperty("database", "defaultDatabase"); } // Bad Practice #3: Making direct connections return DriverManager.getConnection(props.getProperty("url"), props); } } ``` -------------------------------- ### Handle Get Instance Request Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/VertxExample/README.md This method queries the database to get the current Aurora PostgreSQL instance identifier and its role (reader or writer). It then returns this information as a JSON response. ```java private void getCurrentInstance(RoutingContext routingContext) { write.query("select pg_catalog.aurora_db_instance_identifier() as id, case when pg_catalog.pg_is_in_recovery() then 'reader' else 'writer' end as role") .execute() .onSuccess( rows -> { for (Row row : rows) { Instance instance = new Instance( row.getString("id"), row.getString("role")); routingContext.response() .putHeader("content-type", "application/json") .setStatusCode(200) .end(Json.encodePrettily(instance)); } }) .onFailure(e -> { System.out.println("failure: " + e); // handle the failure }); } ``` -------------------------------- ### Create Configuration Profile Based on Existing Profile Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/UsingTheJdbcDriver.md Create a new configuration profile by extending an existing one, allowing for modifications like adding a custom dialect. Also shows how to remove a profile. ```java ConfigurationProfileBuilder.from("existingProfileName") .withName("newProfileName") .withDialect(new CustomDatabaseDialect()) .buildAndSet(); DriverConfigurationProfiles.remove("testProfile"); ``` -------------------------------- ### Example of Setting Illustration Image Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/wrapper/src/test/resources/federated_auth/adfs-sign-in-page.html An example demonstrating how to use the SetIllustrationImage function to change the illustration image on the HRD page. It requires a PowerShell command to add the image to the active theme first. ```javascript // Example to change illustration image on HRD page after adding the image to active theme: // PSH> Set-AdfsWebTheme -TargetName -AdditionalFileResource @{uri='/adfs/portal/images/hrd.jpg';path='.\hrd.jpg'} // //if (typeof HRD != 'undefined') { // SetIllustrationImage('/adfs/portal/images/hrd.jpg'); //} ``` -------------------------------- ### Build Benchmarks with Gradle Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/benchmarks/README.md Build the benchmark JAR file using the Gradle wrapper. The output JAR will be located in the build/libs directory. ```bash ../gradlew jmhJar ``` -------------------------------- ### Instantiate OpenTelemetrySDK for Telemetry Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/Telemetry.md Configure trace and metrics recording by instantiating `OpenTelemetrySDK`. Ensure the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable is set for the exporter. ```java OtlpGrpcSpanExporter spanExporter = OtlpGrpcSpanExporter.builder().setEndpoint(System.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")).build(); OtlpGrpcMetricExporter metricExporter = OtlpGrpcMetricExporter.builder().setEndpoint(System.getenv("OTEL_EXPORTER_OTLP_ENDPOINT")).build(); SdkTracerProvider tracerProvider = SdkTracerProvider.builder().addSpanProcessor(SimpleSpanProcessor.create(spanExporter)).build(); SdkMeterProvider meterProvider = SdkMeterProvider.builder() .registerMetricReader(PeriodicMetricReader.builder(metricExporter).setInterval(15, TimeUnit.SECONDS).build()) .build(); OpenTelemetrySdk.builder() .setTracerProvider(tracerProvider) .setMeterProvider(meterProvider) .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal(); ``` -------------------------------- ### Example Exception Stack Trace with Context Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/ExceptionContext.md This is an example of a stack trace that includes context information added by the AWS Advanced JDBC Driver. It shows the time of the exception and the methods involved in extending the context. ```java [2026-02-12 03:52:20.542]: [pool-358-thread-1] Current time / The exception raised time. at software.amazon.jdbc.util.WrapperUtils.injectAsSuppressedException(WrapperUtils.java:740) at software.amazon.jdbc.util.WrapperUtils.extendWithContext(WrapperUtils.java:665) at software.amazon.jdbc.util.WrapperUtils.executeWithPlugins(WrapperUtils.java:359) ... 11 more ``` -------------------------------- ### Example Exception with SnapshotStateException Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/ExceptionContext.md This example shows a typical `FailoverFailedSQLException` with an injected `SnapshotStateException`. The state snapshot includes details about the connection's internal services, loaded plugins, caches, and monitoring threads. The latest events list provides a chronological record of significant occurrences. ```text software.amazon.jdbc.plugin.failover.FailoverFailedSQLException: Unable to establish SQL connection to the reader instance. (full stack trace is reduced for the sake of clarity) Suppressed: software.amazon.jdbc.exceptions.SnapshotStateException: State snapshot: ... Latest events: ... (full stack trace is reduced for the sake of clarity) ... 11 more ``` -------------------------------- ### Run Benchmarks with Java Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/benchmarks/README.md Execute the built benchmark JAR file using the Java command. Ensure the JAR filename matches the version produced by the build. ```bash java -jar build/libs/benchmarks-3.3.0-jmh.jar ``` -------------------------------- ### Clone Repository Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/development-guide/DevelopmentGuide.md Clone the AWS Advanced JDBC Wrapper repository to start development. ```bash git clone https://github.com/aws/aws-advanced-jdbc-wrapper.git ``` -------------------------------- ### Java Example Class Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringWildflyExample/README.md A simple Java class to represent data, used in the Spring Boot application. ```java package example; public class Example { int status; int id; public Example(int status, int id) { this.status = status; this.id = id; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Example{" + "status=" + status + ", id='" + id + '}' ; } } ``` -------------------------------- ### Enable the Initial Connection Plugin Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheAuroraInitialConnectionStrategyPlugin.md Enable the initial connection plugin by setting the 'wrapperPlugins' property to 'initialConnection'. ```java properties.setProperty("wrapperPlugins","initialConnection"); ``` -------------------------------- ### Example Connection String with KMS Encryption Plugin Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheKmsEncryptionPlugin.md Connect to the database using the JDBC driver and enable the KMS encryption plugin by setting the `wrapperPlugins` property. Configure the AWS KMS region using `kms.region` and enable audit logging if desired. ```java String url = "jdbc:aws-wrapper:postgresql://your-cluster.cluster-xyz.us-east-1.rds.amazonaws.com:5432/mydb"; Properties props = new Properties(); props.setProperty("user", "username"); props.setProperty("password", "password"); props.setProperty("wrapperPlugins", "kmsEncryption"); props.setProperty("kms.region", "us-east-1"); props.setProperty("auditLoggingEnabled", "true"); Connection conn = DriverManager.getConnection(url, props); ``` -------------------------------- ### DAO Implementation with JdbcTemplate Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringTxFailoverExample/README.md Provides the implementation for the DAO interface using Spring's JdbcTemplate. It fetches all records from the EXAMPLE table. ```java package example; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @Component public class ExampleDaoImpl implements ExampleDao { @Autowired private DataSource dataSource; @Override public List> getAll() { final String sql = "SELECT * FROM EXAMPLE"; final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); return jdbcTemplate.queryForList(sql); } } ``` -------------------------------- ### Create Encryption Metadata Schema (PostgreSQL) Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/KmsEncryptionPluginGuide.md Creates the 'encrypt' schema and installs the 'pgcrypto' extension, which is required for HMAC functions in PostgreSQL. ```sql CREATE SCHEMA encrypt; CREATE EXTENSION IF NOT EXISTS pgcrypto; ``` -------------------------------- ### Configure Host Monitoring Plugin Context Pool via JVM Arguments Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheHostMonitoringPlugin.md Set JVM system properties to configure the behavior of the internal context pool for the Host Monitoring plugins. This example demonstrates setting properties for enabling pooling, max idle count, and lazy initialization. ```bash java -Defm.contextPool.enabled=true -Defm.contextPool.maxIdleCount=50 -Defm.contextPool.lazyInitialization=true -jar your-application.jar ``` -------------------------------- ### Run All Integration Tests on Windows Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/development-guide/IntegrationTests Execute all integration tests using the gradlew command on Windows via cmd. Ensure you are in the project root directory. ```batch cmd /c ./gradlew --no-parallel --no-daemon test-all-environments ``` -------------------------------- ### Service Class with Transactional Annotation Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringTxFailoverExample/README.md Contains the business logic for retrieving data and converting it to Example objects. It is marked with @Transactional for transaction management. ```java package example; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.retry.support.RetrySynchronizationManager; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class ExampleService { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private ExampleDao exampleDao; public List get() { logger.info("Retry Number : {}", RetrySynchronizationManager.getContext().getRetryCount()); List> rows = exampleDao.getAll(); List examples = new ArrayList<>(); for (Map row : rows) { Example obj = new Example(); obj.setId(((Integer) row.get("ID"))); obj.setStatus((Integer) row.get("STATUS")); examples.add(obj); } return examples; } } ``` -------------------------------- ### Navigate to Project Root Source: https://github.com/aws/aws-advanced-jdbc-wrapper/wiki/development-guide/DevelopmentGuide Change the current directory to the root of the cloned repository to access build scripts. ```bash cd aws-advanced-jdbc-wrapper ``` -------------------------------- ### Retryable Annotation Example Source: https://github.com/aws/aws-advanced-jdbc-wrapper/blob/main/examples/SpringHibernateBalancedReaderOneDataSourceExample/CUSTOM_ANNOTATIONS.md The @Retryable annotation is used to handle transient failures during failover events, retrying transactions up to a specified number of attempts. ```java import org.springframework.retry.annotation.Retryable; @Retryable(value = { ShouldRetryTransactionException.class }, maxAttempts = 3) ```