From 95c29d06ef0aa59c7f0605098c0e119ecdbec59f Mon Sep 17 00:00:00 2001 From: Karen Chen Date: Tue, 13 Jun 2023 18:54:17 -0700 Subject: [PATCH 1/6] docs: sample code for wildfly and hibernate --- CHANGELOG.md | 3 + .../FailoverConfigurationGuide.md | 2 +- examples/SpringHibernateExample/README.md | 180 ++++++ .../SpringHibernateExample/build.gradle.kts | 28 + .../SpringHibernateExample/gradle.properties | 16 + .../SpringHibernateExampleApplication.java | 42 ++ .../src/main/java/example/mvp/MVP.java | 67 +++ .../main/java/example/mvp/MVPRepository.java | 23 + .../src/main/resources/application.yml | 23 + .../src/main/resources/mvp.sql | 3 + examples/SpringWildflyExample/README.md | 199 +++++++ .../SpringWildflyExample/gradle.properties | 16 + .../spring/build.gradle.kts | 29 + .../spring/src/main/java/example/MVP.java | 52 ++ .../SpringWildflyExampleApplication.java | 50 ++ .../src/main/resources/application.properties | 17 + .../spring/src/main/resources/mvp.sql | 3 + .../software/amazon/jdbc/main/module.xml | 25 + .../standalone/configuration/standalone.xml | 530 ++++++++++++++++++ settings.gradle.kts | 6 +- 20 files changed, 1312 insertions(+), 2 deletions(-) create mode 100644 examples/SpringHibernateExample/README.md create mode 100644 examples/SpringHibernateExample/build.gradle.kts create mode 100644 examples/SpringHibernateExample/gradle.properties create mode 100644 examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java create mode 100644 examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java create mode 100644 examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java create mode 100644 examples/SpringHibernateExample/src/main/resources/application.yml create mode 100644 examples/SpringHibernateExample/src/main/resources/mvp.sql create mode 100644 examples/SpringWildflyExample/README.md create mode 100644 examples/SpringWildflyExample/gradle.properties create mode 100644 examples/SpringWildflyExample/spring/build.gradle.kts create mode 100644 examples/SpringWildflyExample/spring/src/main/java/example/MVP.java create mode 100644 examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java create mode 100644 examples/SpringWildflyExample/spring/src/main/resources/application.properties create mode 100644 examples/SpringWildflyExample/spring/src/main/resources/mvp.sql create mode 100644 examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml create mode 100644 examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b17b85d..aa09e3a03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Link performance test in table of contents. See [Documentation Table of Contents](https://github.com/awslabs/aws-advanced-jdbc-wrapper/blob/main/docs/Documentation.md). - Cluster URLs are not internally pooled. See [Using Read Write Splitting Plugin Internal Connection Pooling](https://github.com/awslabs/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md#internal-connection-pooling). - The `leastConnections` strategy in the [Using Read Write Splitting Plugin Internal Connection Pooling](https://github.com/awslabs/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md#internal-connection-pooling) at point #3. +- Sample code and tutorial for using the driver with: + - Spring and Hibernate + - Spring and Wildfly ### :bug: Fixed - Pruned null connections in connection tracker plugins ([PR #461](https://github.com/awslabs/aws-advanced-jdbc-wrapper/pull/461)) diff --git a/docs/using-the-jdbc-driver/FailoverConfigurationGuide.md b/docs/using-the-jdbc-driver/FailoverConfigurationGuide.md index af40c1d63..1418261e9 100644 --- a/docs/using-the-jdbc-driver/FailoverConfigurationGuide.md +++ b/docs/using-the-jdbc-driver/FailoverConfigurationGuide.md @@ -24,7 +24,7 @@ A failover time profile refers to a specific combination of failover parameters | `failoverClusterTopologyRefreshRateMs` | `2000` | ### Writer Cluster Endpoints After Failover -Connecting to a writer cluster endpoint after failover can result in a faulty connection because DNS causes a delay in changing the writer cluster. On the AWS DNS server, this change is updated usually between 15-20 seconds, but the other DNS servers sitting between the application and the AWS DNS server may not be updated in time. Using this stale DNS data will most likely cause problems for users, so it is important to keep this is mind. +Connecting to a writer cluster endpoint after failover can result in a faulty connection because DNS causes a delay in changing the writer cluster. On the AWS DNS server, this change is updated usually between 15-20 seconds, but the other DNS servers sitting between the application and the AWS DNS server may not be updated in time. Using the stale DNS data will most likely cause problems for users, so it is important to keep this is mind. ### 2-Node Clusters Using failover with a 2-node cluster is not beneficial because during the failover process involving one writer node and one reader node, the two nodes simply switch roles; the reader becomes the writer and the writer becomes the reader. If failover is triggered because one of the nodes has a problem, this problem will persist because there aren't any extra nodes to take the responsibility of the one that is broken. Three or more database nodes are recommended to improve the stability of the cluster. diff --git a/examples/SpringHibernateExample/README.md b/examples/SpringHibernateExample/README.md new file mode 100644 index 000000000..4d5457422 --- /dev/null +++ b/examples/SpringHibernateExample/README.md @@ -0,0 +1,180 @@ +# Tutorial: Getting Started with the AWS Advanced JDBC Wrapper, Spring Boot and Hibernate + +In this tutorial, you will set up a String Boot and Hibernate application with the AWS Advanced JDBC Wrapper, and use the IAM Authentication plugin to fetch some data from an Aurora PostgreSQL database. + +> Note: this tutorial was written using the following technologies: +> - Spring Boot 2.7.1 +> - Hibernate +> - AWS Advanced JDBC Wrapper 2.1.2 +> - Postgresql 42.5.4 +> - Gradle 7 +> - Java 11 + +You will progress through the following sections: +1. Create a Gradle Spring Boot project +2. Add the required Gradle dependencies +3. Configure the AWS Advanced JDBC Wrapper + +## Pre-requisites +- A database with IAM authentication enabled. This tutorial uses the Aurora PostgreSQL database. For information on how to enable IAM database authentication for Aurora databases, please see the [AWS documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html). + +## Step 1: Create a Gradle Project +Create a Gradle project with the following project hierarchy: + +``` +├───.mvn +│ └───wrapper +├───pom.xml +└───src + ├───main + ├───java + │ └───example + | ├───mvp + | ├───MVP.java + | └───MVPRepository.java + │ └───SpringHibernateExampleApplication.java + └───resources + └───application.yml +``` + +> Note: this sample code assumes the target database contains a table named MVP that can be generated using the SQL queries provided in `src/main/resources/mvp.sql`. + +`SpringHibernateExampleApplication.java` contains the following the code: + +```java +@SpringBootApplication +public class SpringHibernateExampleApplication implements CommandLineRunner { + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + @Autowired + MVPRepository repository; + + @Override + public void run(String... args) { + LOGGER.info("Mvp -> {}", repository.findAll()); + } + + public static void main(String[] args) { + SpringApplication.run(SpringHibernateExampleApplication.class, args); + } +} +``` + +`MVP.java` contains the following code: +```java +package example.mvp; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class MVP { + + @Id + @GeneratedValue + private int mvpId; + + private int status; + + public MVP() { + super(); + } + + public MVP(int id, int status) { + super(); + this.mvpId = id; + this.status = status; + } + + public MVP(int status) { + super(); + this.status = status; + } + + public int getMvpId() { + return mvpId; + } + + public void setMvpId(int id) { + this.mvpId = id; + } + + public int getStatus() { + return status; + } + + public void setStatus(int name) { + this.status = name; + } + + @Override + public String toString() { + return String.format("Mvp [id=%s, status=%s]", mvpId, status); + } +} +``` +Lastly, `MVPRepository.java` contains the following code: +```java +package example.mvp; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MVPRepository extends JpaRepository { + +} +``` + +## Step 2: Add the required Gradle Dependencies +In your `build.gradle.kts`, add the following dependencies. + +``` +dependencies { + implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.postgresql:postgresql") + implementation("software.amazon.jdbc:aws-advanced-jdbc-wrapper") +} +``` + +## Step 3: Configure Spring and Hibernate +Configure Spring to use the AWS Advanced JDBC Driver as the default datasource. + +1. In the `application.yml`, add a new datasource for Spring: + ```yaml + datasource: + url: jdbc:aws-wrapper:postgresql://cluster-endpoint:5432/db + username: jane_doe + driver-class-name: software.amazon.jdbc.Driver + hikari: + data-source-properties: + wrapperPlugins: iam,failover,efm + iamRegion: us-east-2 + iamExpiration: 1320 + exception-override-class-name: software.amazon.jdbc.util.HikariCPSQLException + max-lifetime: 1260000 + ``` + Since Spring 2+ uses Hikari to manage datasources, to configure the driver we would need to specify the `data-source-properties` under `hikari`. + Whenever Hikari is used, we also need to ensure failover exceptions are handled correctly so connections will not be discarded from the pool after failover has occurred. This can be done by overriding the exception handling class. For more information on this, please see [the documentation on HikariCP](../../docs/using-the-jdbc-driver/using-plugins/UsingTheFailoverPlugin.md#hikaricp). + + This example contains some very simple configurations for the IAM Authentication plugin, if you are interested in other configurations related to failover, please visit [the documentation for failover parameters](../../docs/using-the-jdbc-driver/using-plugins/UsingTheFailoverPlugin.md#failover-parameters) +2. Configure Hibernate dialect: + ```properties + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + ``` +3. [Optional] You can enable driver logging by adding the following to `application.yml`: + ```yaml + logging: + level: + software: + amazon: + jdbc: TRACE + ``` + +Start the application by running `./gradlew :springhibernate:bootRun` in the terminal. You should see the application making a connection to the database and fetching data from the MVP table. + +# Summary +This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Wrapper to a simple Spring Boot and Wildfly application. diff --git a/examples/SpringHibernateExample/build.gradle.kts b/examples/SpringHibernateExample/build.gradle.kts new file mode 100644 index 000000000..defd0e6c9 --- /dev/null +++ b/examples/SpringHibernateExample/build.gradle.kts @@ -0,0 +1,28 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("org.springframework.boot") version "2.7.0" + id("io.spring.dependency-management") version "1.1.0" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.postgresql:postgresql:42.5.4") + implementation("software.amazon.awssdk:rds:2.20.49") + implementation(project(":aws-advanced-jdbc-wrapper")) +} diff --git a/examples/SpringHibernateExample/gradle.properties b/examples/SpringHibernateExample/gradle.properties new file mode 100644 index 000000000..dc802102f --- /dev/null +++ b/examples/SpringHibernateExample/gradle.properties @@ -0,0 +1,16 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Do not publish the Jar file for this subproject +nexus.publish=false diff --git a/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java b/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java new file mode 100644 index 000000000..fbee45b01 --- /dev/null +++ b/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java @@ -0,0 +1,42 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import example.mvp.MVPRepository; + +@SpringBootApplication +public class SpringHibernateExampleApplication implements CommandLineRunner { + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + @Autowired + MVPRepository repository; + + @Override + public void run(String... args) { + LOGGER.info("Mvp -> {}", repository.findAll()); + } + + public static void main(String[] args) { + SpringApplication.run(SpringHibernateExampleApplication.class, args); + } +} diff --git a/examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java b/examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java new file mode 100644 index 000000000..803f42a9c --- /dev/null +++ b/examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java @@ -0,0 +1,67 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package example.mvp; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class MVP { + + @Id + @GeneratedValue + private int mvpId; + + private int status; + + public MVP() { + super(); + } + + public MVP(int id, int status) { + super(); + this.mvpId = id; + this.status = status; + } + + public MVP(int status) { + super(); + this.status = status; + } + + public int getMvpId() { + return mvpId; + } + + public void setMvpId(int id) { + this.mvpId = id; + } + + public int getStatus() { + return status; + } + + public void setStatus(int name) { + this.status = name; + } + + @Override + public String toString() { + return String.format("Mvp [id=%s, status=%s]", mvpId, status); + } +} diff --git a/examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java b/examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java new file mode 100644 index 000000000..a808a514b --- /dev/null +++ b/examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java @@ -0,0 +1,23 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package example.mvp; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MVPRepository extends JpaRepository { + +} diff --git a/examples/SpringHibernateExample/src/main/resources/application.yml b/examples/SpringHibernateExample/src/main/resources/application.yml new file mode 100644 index 000000000..1357a4264 --- /dev/null +++ b/examples/SpringHibernateExample/src/main/resources/application.yml @@ -0,0 +1,23 @@ +spring: + datasource: + url: jdbc:aws-wrapper:postgresql://cluster-endpoint:5432/db + username: jane_doe + driver-class-name: software.amazon.jdbc.Driver + hikari: + data-source-properties: + wrapperPlugins: iam,failover,efm + iamRegion: us-east-2 + iamExpiration: 1320 + exception-override-class-name: software.amazon.jdbc.util.HikariCPSQLException + max-lifetime: 1260000 + + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + +logging: + level: + software: + amazon: + jdbc: TRACE diff --git a/examples/SpringHibernateExample/src/main/resources/mvp.sql b/examples/SpringHibernateExample/src/main/resources/mvp.sql new file mode 100644 index 000000000..0a7afa41a --- /dev/null +++ b/examples/SpringHibernateExample/src/main/resources/mvp.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS mvp (status int, mvp_id int); + +INSERT INTO mvp (status, mvp_id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringWildflyExample/README.md b/examples/SpringWildflyExample/README.md new file mode 100644 index 000000000..39e25491d --- /dev/null +++ b/examples/SpringWildflyExample/README.md @@ -0,0 +1,199 @@ +# Tutorial: Getting Started with the AWS Advanced JDBC Wrapper, Spring Boot and Wildfly + +In this tutorial, you will set up a Wildfly and String Boot application with the AWS Advanced JDBC Wrapper, and use the wrapper to execute some simple database operations. + +> Note: this tutorial was written using the following technologies: +> - Spring Boot 2.7.1 +> - Wildfly 26.1.1 Final +> - AWS Advanced JDBC Wrapper 2.1.2 +> - Postgresql 42.5.4 +> - Gradle 7 +> - Java 11 + +You will progress through the following sections: +1. Create a Gradle Spring Boot project +2. Add the required Gradle dependencies +3. Configure the AWS Advanced JDBC Wrapper in Wildfly +4. Use JDBCTemplate to perform some simple database operations + +## Step 1: Create a Gradle Project +Create a Gradle project with the following project hierarchy: + +``` +├───build.gradle.kts +├───spring + └───src + ├───main + ├───java + │ └───example + | │───MVP.java + | └───SpringWildflyExampleApplication.java + └───resources + │ └───application.properties +└───wildfly + └───modules + ├───software + ├───amazon + │ └───jdbc + │ └───main + │ │ │───module.xml + │ │ │───postgresql-42.5.0.jar + │ │ └───aws-advanced-jdbc-wrapper-2.1.2.jar + └───standalone + ├───configuration + ├───amazon + │ └───standalone.xml +``` +> Note: The wildfly directory will contain all the files you have downloaded in step 3. For simplicity, the diagram above only shows the files requiring modifications or need to be added. + +The file `MVP.java` contains the following: +```java +package example; + +public class MVP { + + int status; + int mvpId; + + public MVP(int status, int mvpId) { + this.status = status; + this.mvpId = mvpId; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public int getMvpId() { + return mvpId; + } + + public void setMvpId(int mvpId) { + this.mvpId = mvpId; + } + + @Override + public String toString() { + return "MVP{" + + "status=" + status + + ", mvpId='" + mvpId + + '}'; + } +} +``` + +## Step 2: Add the required Gradle Dependencies +In your `build.gradle.kts`, add the following dependencies. + +``` +dependencies { + implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-web") + runtimeOnly("org.springframework.boot:spring-boot-devtools") + implementation("org.postgresql:postgresql") + implementation("software.amazon.jdbc:aws-advanced-jdbc-wrapper") +} +``` + +## Step 3: Configure Wildfly +> Note: for simplicity, this repository does not contain the entire wildfly application, and instead only contains the modified files. + +Download the Wildfly 26.1.1 Servlet-Only Distribution from the [Wildfly website](https://www.wildfly.org/downloads/). +In the Wildfly `standalone/configuration/standalone.xml` file, configure the AWS Advanced JDBC Wrapper as your datasource by adding the following to the `` section. + +```xml + + jdbc:aws-wrapper:postgresql:/cluster-endpoint:5432/db + wrapper + + foo + bar + + +``` + +If you would like to configure any additional properties for the wrapper, such as the [failover timeouts](../../docs/using-the-jdbc-driver/FailoverConfigurationGuide.md), you can do so through ``: +```xml +180000 +2000 +30000 +2000 +``` + +You also need to add a new module in the `modules` directory. +To add a new module, you need to add a `module.xml` and provide the required driver JAR files. +The folder containing the `module.xml` needs to match the module name, in this example, the module name is `software.amazon.jdbc`. +Since this example uses the PostgreSQL JDBC driver as the target driver, you need to add the AWS Advanced JDBC driver JAR file as well as the PostgreSQL JDBC driver JAR file in the same directory as the `module.xml`. + +```xml + + + + + + + +``` + +## Step 4: Configure Spring to use the AWS Advanced JDBC Driver +To configure Spring to use the datasource specified in Wildfly, add an `application.properties` file in `spring/main/resources` with the `jndi-name` property: +```properties +spring.datasource.jndi-name=java:jboss/datasources/AWSWrapper +``` +The `jndi-name` needs to match the JNDI name specified in the Wildfly `standalone.xml` file. + +## Step 4: Use JDBCTemplate to perform some simple operations + +In `spring/src/main/java/example/SpringWildflyExampleApplication.java`, use `JdbcTemplate` to query data from the database. + +> Note: this sample code assumes the target database contains a table named MVP that can be generated using the SQL queries provided in `src/main/resources/mvp.sql`. + +```java +package example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.jdbc.core.JdbcTemplate; + +@SpringBootApplication +public class SpringWildflyExampleApplication implements CommandLineRunner { + + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + @Autowired + JdbcTemplate jdbcTemplate; + + @Override + public void run(String... args) { + LOGGER.info("Mvp -> {}", jdbcTemplate.query( + "SELECT * FROM mvp LIMIT 10", + (rs, rowNum) -> + new MVP( + rs.getInt("status"), + rs.getInt("mvp_id") + ) + )); + } + + public static void main(String[] args) { + SpringApplication.run(SpringWildflyExampleApplication.class, args); + } +} +``` + +Start the application by +1. Starting the Wildfly server with `./wildfly/bin/standalone.sh`, and +2. Running `./gradlew :springhibernate:bootRun` in the terminal. + +3. You should see the Spring application making a connection to the database and fetching data from the MVP table. + +# Summary +This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Wrapper to a simple Spring Boot and Wildfly application. diff --git a/examples/SpringWildflyExample/gradle.properties b/examples/SpringWildflyExample/gradle.properties new file mode 100644 index 000000000..dc802102f --- /dev/null +++ b/examples/SpringWildflyExample/gradle.properties @@ -0,0 +1,16 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Do not publish the Jar file for this subproject +nexus.publish=false diff --git a/examples/SpringWildflyExample/spring/build.gradle.kts b/examples/SpringWildflyExample/spring/build.gradle.kts new file mode 100644 index 000000000..b11fb2096 --- /dev/null +++ b/examples/SpringWildflyExample/spring/build.gradle.kts @@ -0,0 +1,29 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("org.springframework.boot") version "2.7.0" + id("io.spring.dependency-management") version "1.1.0" +} + +dependencies { + implementation("org.springframework.boot:spring-boot-starter-jdbc") + implementation("org.springframework.boot:spring-boot-starter-web") + runtimeOnly("org.springframework.boot:spring-boot-devtools") + implementation("org.postgresql:postgresql:42.5.4") + implementation("software.amazon.awssdk:rds:2.20.49") + implementation(project(":aws-advanced-jdbc-wrapper")) +} diff --git a/examples/SpringWildflyExample/spring/src/main/java/example/MVP.java b/examples/SpringWildflyExample/spring/src/main/java/example/MVP.java new file mode 100644 index 000000000..15278e809 --- /dev/null +++ b/examples/SpringWildflyExample/spring/src/main/java/example/MVP.java @@ -0,0 +1,52 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package example; + +public class MVP { + + int status; + int mvpId; + + public MVP(int status, int mvpId) { + this.status = status; + this.mvpId = mvpId; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public int getMvpId() { + return mvpId; + } + + public void setMvpId(int mvpId) { + this.mvpId = mvpId; + } + + @Override + public String toString() { + return "MVP{" + + "status=" + status + + ", mvpId='" + mvpId + + '}'; + } +} diff --git a/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java b/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java new file mode 100644 index 000000000..fb5c1d355 --- /dev/null +++ b/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java @@ -0,0 +1,50 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package example; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.jdbc.core.JdbcTemplate; + +@SpringBootApplication +public class SpringWildflyExampleApplication implements CommandLineRunner { + + private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); + + @Autowired + JdbcTemplate jdbcTemplate; + + @Override + public void run(String... args) { + LOGGER.info("Mvp -> {}", jdbcTemplate.query( + "SELECT * FROM mvp LIMIT 10", + (rs, rowNum) -> + new MVP( + rs.getInt("status"), + rs.getInt("mvp_id") + ) + )); + } + + public static void main(String[] args) { + SpringApplication.run(SpringWildflyExampleApplication.class, args); + } +} diff --git a/examples/SpringWildflyExample/spring/src/main/resources/application.properties b/examples/SpringWildflyExample/spring/src/main/resources/application.properties new file mode 100644 index 000000000..cbdd3309b --- /dev/null +++ b/examples/SpringWildflyExample/spring/src/main/resources/application.properties @@ -0,0 +1,17 @@ +# +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +spring.datasource.jndi-name=java:jboss/datasources/AWSWrapper diff --git a/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql b/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql new file mode 100644 index 000000000..0a7afa41a --- /dev/null +++ b/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS mvp (status int, mvp_id int); + +INSERT INTO mvp (status, mvp_id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml new file mode 100644 index 000000000..1359d609a --- /dev/null +++ b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml b/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml new file mode 100644 index 000000000..b1a0a3a8d --- /dev/null +++ b/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=${wildfly.h2.compatibility.mode:REGULAR} + h2 + + sa + sa + + + + + org.h2.jdbcx.JdbcDataSource + + + + jdbc:aws-wrapper:postgresql:/cluster-endpoint:5432/db + wrapper + 180000 + 2000 + 30000 + 2000 + + foo + bar + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${jboss.bind.address:127.0.0.1} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index c045631a6..43bb5a02a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,13 +21,17 @@ include( "benchmarks", "hibernate", "hikari", - "driverexample" + "driverexample", + "springhibernate", + "springwildfly" ) project(":aws-advanced-jdbc-wrapper").projectDir = file("wrapper") project(":hibernate").projectDir = file("examples/HibernateExample") project(":hikari").projectDir = file("examples/HikariExample") project(":driverexample").projectDir = file("examples/AWSDriverExample") +project(":springhibernate").projectDir = file("examples/SpringHibernateExample") +project(":springwildfly").projectDir = file("examples/SpringWildflyExample/spring") pluginManagement { plugins { From 213b958630fc44e62fce01589ba0f382f1067ce9 Mon Sep 17 00:00:00 2001 From: Karen Chen Date: Tue, 13 Jun 2023 20:31:27 -0700 Subject: [PATCH 2/6] chore: downgrade testcontainer mariadb version --- wrapper/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrapper/build.gradle.kts b/wrapper/build.gradle.kts index 302482dd6..08a1d79f2 100644 --- a/wrapper/build.gradle.kts +++ b/wrapper/build.gradle.kts @@ -57,8 +57,8 @@ dependencies { testImplementation("software.amazon.awssdk:secretsmanager:2.20.49") testImplementation("org.testcontainers:testcontainers:1.17.4") testImplementation("org.testcontainers:mysql:1.18.0") - testImplementation("org.testcontainers:postgresql:1.17.5") - testImplementation("org.testcontainers:mariadb:1.18.3") + testImplementation("org.testcontainers:postgresql:1.18.0") + testImplementation("org.testcontainers:mariadb:1.18.0") testImplementation("org.testcontainers:junit-jupiter:1.17.4") testImplementation("org.testcontainers:toxiproxy:1.17.5") testImplementation("org.apache.poi:poi-ooxml:5.2.2") From 7e558bdc0923cbde138ef30c046e443d90ec9e31 Mon Sep 17 00:00:00 2001 From: Karen <64801825+karenc-bq@users.noreply.github.com> Date: Wed, 14 Jun 2023 10:14:47 -0700 Subject: [PATCH 3/6] chore: address comments --- CHANGELOG.md | 4 +- examples/SpringHibernateExample/README.md | 107 +++++++++--------- .../SpringHibernateExampleApplication.java | 6 +- .../{mvp/MVP.java => data/Example.java} | 24 ++-- .../ExampleRepository.java} | 4 +- .../src/main/resources/application.yml | 2 +- .../src/main/resources/example.sql | 17 +++ .../src/main/resources/mvp.sql | 3 - examples/SpringWildflyExample/README.md | 50 ++++---- .../java/example/{MVP.java => Example.java} | 20 ++-- .../SpringWildflyExampleApplication.java | 8 +- .../spring/src/main/resources/example.sql | 17 +++ .../spring/src/main/resources/mvp.sql | 3 - .../standalone/configuration/standalone.xml | 2 +- wrapper/build.gradle.kts | 8 +- .../integration/util/ContainerHelper.java | 2 +- 16 files changed, 152 insertions(+), 125 deletions(-) rename examples/SpringHibernateExample/src/main/java/example/{mvp/MVP.java => data/Example.java} (76%) rename examples/SpringHibernateExample/src/main/java/example/{mvp/MVPRepository.java => data/ExampleRepository.java} (87%) create mode 100644 examples/SpringHibernateExample/src/main/resources/example.sql delete mode 100644 examples/SpringHibernateExample/src/main/resources/mvp.sql rename examples/SpringWildflyExample/spring/src/main/java/example/{MVP.java => Example.java} (78%) create mode 100644 examples/SpringWildflyExample/spring/src/main/resources/example.sql delete mode 100644 examples/SpringWildflyExample/spring/src/main/resources/mvp.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index aa09e3a03..bef4b6fd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,8 +16,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Cluster URLs are not internally pooled. See [Using Read Write Splitting Plugin Internal Connection Pooling](https://github.com/awslabs/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md#internal-connection-pooling). - The `leastConnections` strategy in the [Using Read Write Splitting Plugin Internal Connection Pooling](https://github.com/awslabs/aws-advanced-jdbc-wrapper/blob/main/docs/using-the-jdbc-driver/using-plugins/UsingTheReadWriteSplittingPlugin.md#internal-connection-pooling) at point #3. - Sample code and tutorial for using the driver with: - - Spring and Hibernate - - Spring and Wildfly + - [Spring and Hibernate](./examples/SpringHibernateExample/README.md) + - [Spring and Wildfly](./examples/SpringWildflyExample/README.md) ### :bug: Fixed - Pruned null connections in connection tracker plugins ([PR #461](https://github.com/awslabs/aws-advanced-jdbc-wrapper/pull/461)) diff --git a/examples/SpringHibernateExample/README.md b/examples/SpringHibernateExample/README.md index 4d5457422..ff74b7940 100644 --- a/examples/SpringHibernateExample/README.md +++ b/examples/SpringHibernateExample/README.md @@ -1,11 +1,11 @@ -# Tutorial: Getting Started with the AWS Advanced JDBC Wrapper, Spring Boot and Hibernate +# Tutorial: Getting Started with the AWS Advanced JDBC Driver, Spring Boot and Hibernate -In this tutorial, you will set up a String Boot and Hibernate application with the AWS Advanced JDBC Wrapper, and use the IAM Authentication plugin to fetch some data from an Aurora PostgreSQL database. +In this tutorial, you will set up a Spring Boot and Hibernate application with the AWS Advanced JDBC Driver, and use the IAM Authentication plugin to fetch some data from an Aurora PostgreSQL database. > Note: this tutorial was written using the following technologies: > - Spring Boot 2.7.1 > - Hibernate -> - AWS Advanced JDBC Wrapper 2.1.2 +> - AWS Advanced JDBC Driver 2.1.2 > - Postgresql 42.5.4 > - Gradle 7 > - Java 11 @@ -13,7 +13,7 @@ In this tutorial, you will set up a String Boot and Hibernate application with t You will progress through the following sections: 1. Create a Gradle Spring Boot project 2. Add the required Gradle dependencies -3. Configure the AWS Advanced JDBC Wrapper +3. Configure the AWS Advanced JDBC Driver ## Pre-requisites - A database with IAM authentication enabled. This tutorial uses the Aurora PostgreSQL database. For information on how to enable IAM database authentication for Aurora databases, please see the [AWS documentation](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html). @@ -22,22 +22,19 @@ You will progress through the following sections: Create a Gradle project with the following project hierarchy: ``` -├───.mvn -│ └───wrapper -├───pom.xml └───src ├───main ├───java │ └───example - | ├───mvp - | ├───MVP.java - | └───MVPRepository.java + | ├───data + | ├───Example.java + | └───ExampleRepository.java │ └───SpringHibernateExampleApplication.java └───resources └───application.yml ``` -> Note: this sample code assumes the target database contains a table named MVP that can be generated using the SQL queries provided in `src/main/resources/mvp.sql`. +> Note: this sample code assumes the target database contains a table named Example that can be generated using the SQL queries provided in `src/main/resources/example.sql`. `SpringHibernateExampleApplication.java` contains the following the code: @@ -47,11 +44,11 @@ public class SpringHibernateExampleApplication implements CommandLineRunner { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); @Autowired - MVPRepository repository; + ExampleRepository repository; @Override public void run(String... args) { - LOGGER.info("Mvp -> {}", repository.findAll()); + LOGGER.info("Example -> {}", repository.findAll()); } public static void main(String[] args) { @@ -60,67 +57,69 @@ public class SpringHibernateExampleApplication implements CommandLineRunner { } ``` -`MVP.java` contains the following code: +`Example.java` contains the following code: + ```java -package example.mvp; +package example.data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity -public class MVP { +public class Example { - @Id - @GeneratedValue - private int mvpId; + @Id + @GeneratedValue + private int id; - private int status; + private int status; - public MVP() { - super(); - } + public Example() { + super(); + } - public MVP(int id, int status) { - super(); - this.mvpId = id; - this.status = status; - } + public Example(int id, int status) { + super(); + this.id = id; + this.status = status; + } - public MVP(int status) { - super(); - this.status = status; - } + public Example(int status) { + super(); + this.status = status; + } - public int getMvpId() { - return mvpId; - } + public int getId() { + return id; + } - public void setMvpId(int id) { - this.mvpId = id; - } + public void setId(int id) { + this.id = id; + } - public int getStatus() { - return status; - } + public int getStatus() { + return status; + } - public void setStatus(int name) { - this.status = name; - } + public void setStatus(int name) { + this.status = name; + } - @Override - public String toString() { - return String.format("Mvp [id=%s, status=%s]", mvpId, status); - } + @Override + public String toString() { + return String.format("Example [id=%s, status=%s]", id, status); + } } ``` -Lastly, `MVPRepository.java` contains the following code: +Lastly, `ExampleRepository.java` contains the following code: + ```java -package example.mvp; +package example.data; import org.springframework.data.jpa.repository.JpaRepository; -public interface MVPRepository extends JpaRepository { +public interface ExampleRepository extends JpaRepository { } ``` @@ -143,7 +142,7 @@ Configure Spring to use the AWS Advanced JDBC Driver as the default datasource. 1. In the `application.yml`, add a new datasource for Spring: ```yaml datasource: - url: jdbc:aws-wrapper:postgresql://cluster-endpoint:5432/db + url: jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/db username: jane_doe driver-class-name: software.amazon.jdbc.Driver hikari: @@ -174,7 +173,7 @@ Configure Spring to use the AWS Advanced JDBC Driver as the default datasource. jdbc: TRACE ``` -Start the application by running `./gradlew :springhibernate:bootRun` in the terminal. You should see the application making a connection to the database and fetching data from the MVP table. +Start the application by running `./gradlew :springhibernate:bootRun` in the terminal. You should see the application making a connection to the database and fetching data from the Example table. # Summary -This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Wrapper to a simple Spring Boot and Wildfly application. +This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Driver to a simple Spring Boot and Hibernate application. diff --git a/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java b/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java index fbee45b01..501f980a5 100644 --- a/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java +++ b/examples/SpringHibernateExample/src/main/java/example/SpringHibernateExampleApplication.java @@ -22,18 +22,18 @@ import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import example.mvp.MVPRepository; +import example.data.ExampleRepository; @SpringBootApplication public class SpringHibernateExampleApplication implements CommandLineRunner { private final Logger LOGGER = LoggerFactory.getLogger(this.getClass()); @Autowired - MVPRepository repository; + ExampleRepository repository; @Override public void run(String... args) { - LOGGER.info("Mvp -> {}", repository.findAll()); + LOGGER.info("Example -> {}", repository.findAll()); } public static void main(String[] args) { diff --git a/examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java b/examples/SpringHibernateExample/src/main/java/example/data/Example.java similarity index 76% rename from examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java rename to examples/SpringHibernateExample/src/main/java/example/data/Example.java index 803f42a9c..92165b640 100644 --- a/examples/SpringHibernateExample/src/main/java/example/mvp/MVP.java +++ b/examples/SpringHibernateExample/src/main/java/example/data/Example.java @@ -14,42 +14,42 @@ * limitations under the License. */ -package example.mvp; +package example.data; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity -public class MVP { +public class Example { @Id @GeneratedValue - private int mvpId; + private int id; private int status; - public MVP() { + public Example() { super(); } - public MVP(int id, int status) { + public Example(int id, int status) { super(); - this.mvpId = id; + this.id = id; this.status = status; } - public MVP(int status) { + public Example(int status) { super(); this.status = status; } - public int getMvpId() { - return mvpId; + public int getId() { + return id; } - public void setMvpId(int id) { - this.mvpId = id; + public void setId(int id) { + this.id = id; } public int getStatus() { @@ -62,6 +62,6 @@ public void setStatus(int name) { @Override public String toString() { - return String.format("Mvp [id=%s, status=%s]", mvpId, status); + return String.format("Example [id=%s, status=%s]", id, status); } } diff --git a/examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java b/examples/SpringHibernateExample/src/main/java/example/data/ExampleRepository.java similarity index 87% rename from examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java rename to examples/SpringHibernateExample/src/main/java/example/data/ExampleRepository.java index a808a514b..7fd92f11b 100644 --- a/examples/SpringHibernateExample/src/main/java/example/mvp/MVPRepository.java +++ b/examples/SpringHibernateExample/src/main/java/example/data/ExampleRepository.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package example.mvp; +package example.data; import org.springframework.data.jpa.repository.JpaRepository; -public interface MVPRepository extends JpaRepository { +public interface ExampleRepository extends JpaRepository { } diff --git a/examples/SpringHibernateExample/src/main/resources/application.yml b/examples/SpringHibernateExample/src/main/resources/application.yml index 1357a4264..4872404f2 100644 --- a/examples/SpringHibernateExample/src/main/resources/application.yml +++ b/examples/SpringHibernateExample/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:aws-wrapper:postgresql://cluster-endpoint:5432/db + url: jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/db username: jane_doe driver-class-name: software.amazon.jdbc.Driver hikari: diff --git a/examples/SpringHibernateExample/src/main/resources/example.sql b/examples/SpringHibernateExample/src/main/resources/example.sql new file mode 100644 index 000000000..c5ac40c81 --- /dev/null +++ b/examples/SpringHibernateExample/src/main/resources/example.sql @@ -0,0 +1,17 @@ +-- Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"). +-- You may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +CREATE TABLE IF NOT EXISTS example (status int, id int); + +INSERT INTO example (status, id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringHibernateExample/src/main/resources/mvp.sql b/examples/SpringHibernateExample/src/main/resources/mvp.sql deleted file mode 100644 index 0a7afa41a..000000000 --- a/examples/SpringHibernateExample/src/main/resources/mvp.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TABLE IF NOT EXISTS mvp (status int, mvp_id int); - -INSERT INTO mvp (status, mvp_id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringWildflyExample/README.md b/examples/SpringWildflyExample/README.md index 39e25491d..7d00e3d76 100644 --- a/examples/SpringWildflyExample/README.md +++ b/examples/SpringWildflyExample/README.md @@ -1,6 +1,6 @@ -# Tutorial: Getting Started with the AWS Advanced JDBC Wrapper, Spring Boot and Wildfly +# Tutorial: Getting Started with the AWS Advanced JDBC Driver, Spring Boot and Wildfly -In this tutorial, you will set up a Wildfly and String Boot application with the AWS Advanced JDBC Wrapper, and use the wrapper to execute some simple database operations. +In this tutorial, you will set up a Wildfly and Spring Boot application with the AWS Advanced JDBC Driver, and use the wrapper to execute some simple database operations. > Note: this tutorial was written using the following technologies: > - Spring Boot 2.7.1 @@ -26,7 +26,7 @@ Create a Gradle project with the following project hierarchy: ├───main ├───java │ └───example - | │───MVP.java + | │───Example.java | └───SpringWildflyExampleApplication.java └───resources │ └───application.properties @@ -37,7 +37,7 @@ Create a Gradle project with the following project hierarchy: │ └───jdbc │ └───main │ │ │───module.xml - │ │ │───postgresql-42.5.0.jar + │ │ │───postgresql-42.5.4.jar │ │ └───aws-advanced-jdbc-wrapper-2.1.2.jar └───standalone ├───configuration @@ -46,18 +46,18 @@ Create a Gradle project with the following project hierarchy: ``` > Note: The wildfly directory will contain all the files you have downloaded in step 3. For simplicity, the diagram above only shows the files requiring modifications or need to be added. -The file `MVP.java` contains the following: +The file `Example.java` contains the following: ```java package example; -public class MVP { +public class Example { int status; - int mvpId; + int id; - public MVP(int status, int mvpId) { + public Example(int status, int id) { this.status = status; - this.mvpId = mvpId; + this.id = id; } public int getStatus() { @@ -68,19 +68,19 @@ public class MVP { this.status = status; } - public int getMvpId() { - return mvpId; + public int getId() { + return id; } - public void setMvpId(int mvpId) { - this.mvpId = mvpId; + public void setId(int id) { + this.id = id; } @Override public String toString() { - return "MVP{" + + return "Example{" + "status=" + status + - ", mvpId='" + mvpId + + ", id='" + id + '}'; } } @@ -103,11 +103,11 @@ dependencies { > Note: for simplicity, this repository does not contain the entire wildfly application, and instead only contains the modified files. Download the Wildfly 26.1.1 Servlet-Only Distribution from the [Wildfly website](https://www.wildfly.org/downloads/). -In the Wildfly `standalone/configuration/standalone.xml` file, configure the AWS Advanced JDBC Wrapper as your datasource by adding the following to the `` section. +In the Wildfly `standalone/configuration/standalone.xml` file, configure the AWS Advanced JDBC Driver as your datasource by adding the following to the `` section. ```xml - jdbc:aws-wrapper:postgresql:/cluster-endpoint:5432/db + jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/db wrapper foo @@ -127,7 +127,7 @@ If you would like to configure any additional properties for the wrapper, such a You also need to add a new module in the `modules` directory. To add a new module, you need to add a `module.xml` and provide the required driver JAR files. The folder containing the `module.xml` needs to match the module name, in this example, the module name is `software.amazon.jdbc`. -Since this example uses the PostgreSQL JDBC driver as the target driver, you need to add the AWS Advanced JDBC driver JAR file as well as the PostgreSQL JDBC driver JAR file in the same directory as the `module.xml`. +Since this example uses the PostgreSQL JDBC driver as the target driver, you need to add the AWS Advanced JDBC Driver JAR file as well as the PostgreSQL JDBC driver JAR file in the same directory as the `module.xml`. ```xml @@ -150,7 +150,7 @@ The `jndi-name` needs to match the JNDI name specified in the Wildfly `standalon In `spring/src/main/java/example/SpringWildflyExampleApplication.java`, use `JdbcTemplate` to query data from the database. -> Note: this sample code assumes the target database contains a table named MVP that can be generated using the SQL queries provided in `src/main/resources/mvp.sql`. +> Note: this sample code assumes the target database contains a table named Example that can be generated using the SQL queries provided in `src/main/resources/example.sql`. ```java package example; @@ -173,12 +173,12 @@ public class SpringWildflyExampleApplication implements CommandLineRunner { @Override public void run(String... args) { - LOGGER.info("Mvp -> {}", jdbcTemplate.query( - "SELECT * FROM mvp LIMIT 10", + LOGGER.info("Example -> {}", jdbcTemplate.query( + "SELECT * FROM example LIMIT 10", (rs, rowNum) -> - new MVP( + new Example( rs.getInt("status"), - rs.getInt("mvp_id") + rs.getInt("id") ) )); } @@ -193,7 +193,7 @@ Start the application by 1. Starting the Wildfly server with `./wildfly/bin/standalone.sh`, and 2. Running `./gradlew :springhibernate:bootRun` in the terminal. -3. You should see the Spring application making a connection to the database and fetching data from the MVP table. +3. You should see the Spring application making a connection to the database and fetching data from the Example table. # Summary -This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Wrapper to a simple Spring Boot and Wildfly application. +This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Driver to a simple Spring Boot and Wildfly application. diff --git a/examples/SpringWildflyExample/spring/src/main/java/example/MVP.java b/examples/SpringWildflyExample/spring/src/main/java/example/Example.java similarity index 78% rename from examples/SpringWildflyExample/spring/src/main/java/example/MVP.java rename to examples/SpringWildflyExample/spring/src/main/java/example/Example.java index 15278e809..ef856148c 100644 --- a/examples/SpringWildflyExample/spring/src/main/java/example/MVP.java +++ b/examples/SpringWildflyExample/spring/src/main/java/example/Example.java @@ -16,14 +16,14 @@ package example; -public class MVP { +public class Example { int status; - int mvpId; + int id; - public MVP(int status, int mvpId) { + public Example(int status, int id) { this.status = status; - this.mvpId = mvpId; + this.id = id; } public int getStatus() { @@ -34,19 +34,19 @@ public void setStatus(int status) { this.status = status; } - public int getMvpId() { - return mvpId; + public int getId() { + return id; } - public void setMvpId(int mvpId) { - this.mvpId = mvpId; + public void setId(int id) { + this.id = id; } @Override public String toString() { - return "MVP{" + + return "Example{" + "status=" + status + - ", mvpId='" + mvpId + + ", id='" + id + '}'; } } diff --git a/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java b/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java index fb5c1d355..a4eb86c2b 100644 --- a/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java +++ b/examples/SpringWildflyExample/spring/src/main/java/example/SpringWildflyExampleApplication.java @@ -34,12 +34,12 @@ public class SpringWildflyExampleApplication implements CommandLineRunner { @Override public void run(String... args) { - LOGGER.info("Mvp -> {}", jdbcTemplate.query( - "SELECT * FROM mvp LIMIT 10", + LOGGER.info("Example -> {}", jdbcTemplate.query( + "SELECT * FROM example LIMIT 10", (rs, rowNum) -> - new MVP( + new Example( rs.getInt("status"), - rs.getInt("mvp_id") + rs.getInt("id") ) )); } diff --git a/examples/SpringWildflyExample/spring/src/main/resources/example.sql b/examples/SpringWildflyExample/spring/src/main/resources/example.sql new file mode 100644 index 000000000..c5ac40c81 --- /dev/null +++ b/examples/SpringWildflyExample/spring/src/main/resources/example.sql @@ -0,0 +1,17 @@ +-- Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +-- +-- Licensed under the Apache License, Version 2.0 (the "License"). +-- You may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +CREATE TABLE IF NOT EXISTS example (status int, id int); + +INSERT INTO example (status, id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql b/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql deleted file mode 100644 index 0a7afa41a..000000000 --- a/examples/SpringWildflyExample/spring/src/main/resources/mvp.sql +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TABLE IF NOT EXISTS mvp (status int, mvp_id int); - -INSERT INTO mvp (status, mvp_id) VALUES (66608, 104), (754, 148); diff --git a/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml b/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml index b1a0a3a8d..01cb99a57 100644 --- a/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml +++ b/examples/SpringWildflyExample/wildfly/standalone/configuration/standalone.xml @@ -141,7 +141,7 @@ - jdbc:aws-wrapper:postgresql:/cluster-endpoint:5432/db + jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/db wrapper 180000 2000 diff --git a/wrapper/build.gradle.kts b/wrapper/build.gradle.kts index 08a1d79f2..944e60137 100644 --- a/wrapper/build.gradle.kts +++ b/wrapper/build.gradle.kts @@ -55,10 +55,10 @@ dependencies { testImplementation("software.amazon.awssdk:rds:2.20.49") testImplementation("software.amazon.awssdk:ec2:2.20.61") testImplementation("software.amazon.awssdk:secretsmanager:2.20.49") - testImplementation("org.testcontainers:testcontainers:1.17.4") - testImplementation("org.testcontainers:mysql:1.18.0") - testImplementation("org.testcontainers:postgresql:1.18.0") - testImplementation("org.testcontainers:mariadb:1.18.0") + testImplementation("org.testcontainers:testcontainers:1.18.3") + testImplementation("org.testcontainers:mysql:1.18.3") + testImplementation("org.testcontainers:postgresql:1.18.3") + testImplementation("org.testcontainers:mariadb:1.18.3") testImplementation("org.testcontainers:junit-jupiter:1.17.4") testImplementation("org.testcontainers:toxiproxy:1.17.5") testImplementation("org.apache.poi:poi-ooxml:5.2.2") diff --git a/wrapper/src/test/java/integration/util/ContainerHelper.java b/wrapper/src/test/java/integration/util/ContainerHelper.java index 62af047e9..6e91ca0d2 100644 --- a/wrapper/src/test/java/integration/util/ContainerHelper.java +++ b/wrapper/src/test/java/integration/util/ContainerHelper.java @@ -49,7 +49,7 @@ public class ContainerHelper { private static final String MYSQL_CONTAINER_IMAGE_NAME = "mysql:latest"; private static final String POSTGRES_CONTAINER_IMAGE_NAME = "postgres:latest"; - private static final String MARIADB_CONTAINER_IMAGE_NAME = "mariadb:latest"; + private static final String MARIADB_CONTAINER_IMAGE_NAME = "mariadb:10"; private static final DockerImageName TOXIPROXY_IMAGE = DockerImageName.parse("shopify/toxiproxy:2.1.4"); From ad7c70fc4b5557b1d01646bde79876fde6cada73 Mon Sep 17 00:00:00 2001 From: Karen Chen Date: Wed, 14 Jun 2023 14:44:29 -0700 Subject: [PATCH 4/6] chore: bump driver version --- examples/SpringHibernateExample/README.md | 2 +- examples/SpringWildflyExample/README.md | 6 +++--- .../wildfly/modules/software/amazon/jdbc/main/module.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/SpringHibernateExample/README.md b/examples/SpringHibernateExample/README.md index ff74b7940..fbb63845f 100644 --- a/examples/SpringHibernateExample/README.md +++ b/examples/SpringHibernateExample/README.md @@ -5,7 +5,7 @@ In this tutorial, you will set up a Spring Boot and Hibernate application with t > Note: this tutorial was written using the following technologies: > - Spring Boot 2.7.1 > - Hibernate -> - AWS Advanced JDBC Driver 2.1.2 +> - AWS Advanced JDBC Driver 2.2.0 > - Postgresql 42.5.4 > - Gradle 7 > - Java 11 diff --git a/examples/SpringWildflyExample/README.md b/examples/SpringWildflyExample/README.md index 7d00e3d76..3ea537f55 100644 --- a/examples/SpringWildflyExample/README.md +++ b/examples/SpringWildflyExample/README.md @@ -5,7 +5,7 @@ In this tutorial, you will set up a Wildfly and Spring Boot application with the > Note: this tutorial was written using the following technologies: > - Spring Boot 2.7.1 > - Wildfly 26.1.1 Final -> - AWS Advanced JDBC Wrapper 2.1.2 +> - AWS Advanced JDBC Wrapper 2.2.0 > - Postgresql 42.5.4 > - Gradle 7 > - Java 11 @@ -38,7 +38,7 @@ Create a Gradle project with the following project hierarchy: │ └───main │ │ │───module.xml │ │ │───postgresql-42.5.4.jar - │ │ └───aws-advanced-jdbc-wrapper-2.1.2.jar + │ │ └───aws-advanced-jdbc-wrapper-2.2.0.jar └───standalone ├───configuration ├───amazon @@ -133,7 +133,7 @@ Since this example uses the PostgreSQL JDBC driver as the target driver, you nee - + diff --git a/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml index 1359d609a..3f8dc8b3a 100644 --- a/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml +++ b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml @@ -19,7 +19,7 @@ - + From aa1bf937801d2b1fd5447a98bf88f5472169eb4a Mon Sep 17 00:00:00 2001 From: Karen Chen Date: Wed, 14 Jun 2023 14:48:13 -0700 Subject: [PATCH 5/6] chore: bump driver version --- .../wildfly/modules/software/amazon/jdbc/main/module.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml index 3f8dc8b3a..ddbf34869 100644 --- a/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml +++ b/examples/SpringWildflyExample/wildfly/modules/software/amazon/jdbc/main/module.xml @@ -20,6 +20,6 @@ - + From aa36eece5cd133ba5bba8e5956eeee5fd5d7cdc8 Mon Sep 17 00:00:00 2001 From: Karen Chen Date: Wed, 14 Jun 2023 15:20:12 -0700 Subject: [PATCH 6/6] chore: bump driver version --- examples/SpringWildflyExample/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SpringWildflyExample/README.md b/examples/SpringWildflyExample/README.md index 3ea537f55..2146ec755 100644 --- a/examples/SpringWildflyExample/README.md +++ b/examples/SpringWildflyExample/README.md @@ -134,7 +134,7 @@ Since this example uses the PostgreSQL JDBC driver as the target driver, you nee - + ```