Skip to content

Commit 8b9b22d

Browse files
authored
docs: sample code for wildfly and hibernate (#489)
1 parent b77cb9c commit 8b9b22d

File tree

22 files changed

+1343
-6
lines changed

22 files changed

+1343
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1515
- 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).
1616
- 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).
1717
- 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.
18+
- Sample code and tutorial for using the driver with:
19+
- [Spring and Hibernate](./examples/SpringHibernateExample/README.md)
20+
- [Spring and Wildfly](./examples/SpringWildflyExample/README.md)
1821

1922
### :bug: Fixed
2023
- Pruned null connections in connection tracker plugins ([PR #461](https://github.com/awslabs/aws-advanced-jdbc-wrapper/pull/461))

docs/using-the-jdbc-driver/FailoverConfigurationGuide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ A failover time profile refers to a specific combination of failover parameters
2424
| `failoverClusterTopologyRefreshRateMs` | `2000` |
2525

2626
### Writer Cluster Endpoints After Failover
27-
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.
27+
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.
2828

2929
### 2-Node Clusters
3030
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.
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# Tutorial: Getting Started with the AWS Advanced JDBC Driver, Spring Boot and Hibernate
2+
3+
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.
4+
5+
> Note: this tutorial was written using the following technologies:
6+
> - Spring Boot 2.7.1
7+
> - Hibernate
8+
> - AWS Advanced JDBC Driver 2.2.0
9+
> - Postgresql 42.5.4
10+
> - Gradle 7
11+
> - Java 11
12+
13+
You will progress through the following sections:
14+
1. Create a Gradle Spring Boot project
15+
2. Add the required Gradle dependencies
16+
3. Configure the AWS Advanced JDBC Driver
17+
18+
## Pre-requisites
19+
- 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).
20+
21+
## Step 1: Create a Gradle Project
22+
Create a Gradle project with the following project hierarchy:
23+
24+
```
25+
└───src
26+
├───main
27+
├───java
28+
│ └───example
29+
| ├───data
30+
| ├───Example.java
31+
| └───ExampleRepository.java
32+
│ └───SpringHibernateExampleApplication.java
33+
└───resources
34+
└───application.yml
35+
```
36+
37+
> 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`.
38+
39+
`SpringHibernateExampleApplication.java` contains the following the code:
40+
41+
```java
42+
@SpringBootApplication
43+
public class SpringHibernateExampleApplication implements CommandLineRunner {
44+
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
45+
46+
@Autowired
47+
ExampleRepository repository;
48+
49+
@Override
50+
public void run(String... args) {
51+
LOGGER.info("Example -> {}", repository.findAll());
52+
}
53+
54+
public static void main(String[] args) {
55+
SpringApplication.run(SpringHibernateExampleApplication.class, args);
56+
}
57+
}
58+
```
59+
60+
`Example.java` contains the following code:
61+
62+
```java
63+
package example.data;
64+
65+
import javax.persistence.Entity;
66+
import javax.persistence.GeneratedValue;
67+
import javax.persistence.Id;
68+
69+
@Entity
70+
public class Example {
71+
72+
@Id
73+
@GeneratedValue
74+
private int id;
75+
76+
private int status;
77+
78+
public Example() {
79+
super();
80+
}
81+
82+
public Example(int id, int status) {
83+
super();
84+
this.id = id;
85+
this.status = status;
86+
}
87+
88+
public Example(int status) {
89+
super();
90+
this.status = status;
91+
}
92+
93+
public int getId() {
94+
return id;
95+
}
96+
97+
public void setId(int id) {
98+
this.id = id;
99+
}
100+
101+
public int getStatus() {
102+
return status;
103+
}
104+
105+
public void setStatus(int name) {
106+
this.status = name;
107+
}
108+
109+
@Override
110+
public String toString() {
111+
return String.format("Example [id=%s, status=%s]", id, status);
112+
}
113+
}
114+
```
115+
Lastly, `ExampleRepository.java` contains the following code:
116+
117+
```java
118+
package example.data;
119+
120+
import org.springframework.data.jpa.repository.JpaRepository;
121+
122+
public interface ExampleRepository extends JpaRepository<Example, Integer> {
123+
124+
}
125+
```
126+
127+
## Step 2: Add the required Gradle Dependencies
128+
In your `build.gradle.kts`, add the following dependencies.
129+
130+
```
131+
dependencies {
132+
implementation("org.springframework.boot:spring-boot-starter-jdbc")
133+
implementation("org.springframework.boot:spring-boot-starter-web")
134+
implementation("org.postgresql:postgresql")
135+
implementation("software.amazon.jdbc:aws-advanced-jdbc-wrapper")
136+
}
137+
```
138+
139+
## Step 3: Configure Spring and Hibernate
140+
Configure Spring to use the AWS Advanced JDBC Driver as the default datasource.
141+
142+
1. In the `application.yml`, add a new datasource for Spring:
143+
```yaml
144+
datasource:
145+
url: jdbc:aws-wrapper:postgresql://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:5432/db
146+
username: jane_doe
147+
driver-class-name: software.amazon.jdbc.Driver
148+
hikari:
149+
data-source-properties:
150+
wrapperPlugins: iam,failover,efm
151+
iamRegion: us-east-2
152+
iamExpiration: 1320
153+
exception-override-class-name: software.amazon.jdbc.util.HikariCPSQLException
154+
max-lifetime: 1260000
155+
```
156+
Since Spring 2+ uses Hikari to manage datasources, to configure the driver we would need to specify the `data-source-properties` under `hikari`.
157+
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).
158+
159+
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)
160+
2. Configure Hibernate dialect:
161+
```properties
162+
jpa:
163+
properties:
164+
hibernate:
165+
dialect: org.hibernate.dialect.PostgreSQLDialect
166+
```
167+
3. [Optional] You can enable driver logging by adding the following to `application.yml`:
168+
```yaml
169+
logging:
170+
level:
171+
software:
172+
amazon:
173+
jdbc: TRACE
174+
```
175+
176+
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.
177+
178+
# Summary
179+
This tutorial walks through the steps required to add and configure the AWS Advanced JDBC Driver to a simple Spring Boot and Hibernate application.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
id("org.springframework.boot") version "2.7.0"
19+
id("io.spring.dependency-management") version "1.1.0"
20+
}
21+
22+
dependencies {
23+
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
24+
implementation("org.springframework.boot:spring-boot-starter-web")
25+
implementation("org.postgresql:postgresql:42.5.4")
26+
implementation("software.amazon.awssdk:rds:2.20.49")
27+
implementation(project(":aws-advanced-jdbc-wrapper"))
28+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License").
4+
# You may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Do not publish the Jar file for this subproject
16+
nexus.publish=false
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example;
18+
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
import org.springframework.beans.factory.annotation.Autowired;
22+
import org.springframework.boot.CommandLineRunner;
23+
import org.springframework.boot.SpringApplication;
24+
import org.springframework.boot.autoconfigure.SpringBootApplication;
25+
import example.data.ExampleRepository;
26+
27+
@SpringBootApplication
28+
public class SpringHibernateExampleApplication implements CommandLineRunner {
29+
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
30+
31+
@Autowired
32+
ExampleRepository repository;
33+
34+
@Override
35+
public void run(String... args) {
36+
LOGGER.info("Example -> {}", repository.findAll());
37+
}
38+
39+
public static void main(String[] args) {
40+
SpringApplication.run(SpringHibernateExampleApplication.class, args);
41+
}
42+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.data;
18+
19+
import javax.persistence.Entity;
20+
import javax.persistence.GeneratedValue;
21+
import javax.persistence.Id;
22+
23+
@Entity
24+
public class Example {
25+
26+
@Id
27+
@GeneratedValue
28+
private int id;
29+
30+
private int status;
31+
32+
public Example() {
33+
super();
34+
}
35+
36+
public Example(int id, int status) {
37+
super();
38+
this.id = id;
39+
this.status = status;
40+
}
41+
42+
public Example(int status) {
43+
super();
44+
this.status = status;
45+
}
46+
47+
public int getId() {
48+
return id;
49+
}
50+
51+
public void setId(int id) {
52+
this.id = id;
53+
}
54+
55+
public int getStatus() {
56+
return status;
57+
}
58+
59+
public void setStatus(int name) {
60+
this.status = name;
61+
}
62+
63+
@Override
64+
public String toString() {
65+
return String.format("Example [id=%s, status=%s]", id, status);
66+
}
67+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package example.data;
18+
19+
import org.springframework.data.jpa.repository.JpaRepository;
20+
21+
public interface ExampleRepository extends JpaRepository<Example, Integer> {
22+
23+
}

0 commit comments

Comments
 (0)