From 472ef44d39a7146a5ac7827fd70fd95ce3977855 Mon Sep 17 00:00:00 2001 From: jmformenti Date: Sat, 16 Mar 2024 19:41:58 +0100 Subject: [PATCH 1/4] feat: Database configuration integration with Spring Boot --- pom.xml | 15 +++++++------- readme.md | 20 ++++--------------- .../resources/application-mysql.properties | 2 ++ .../resources/application-postgres.properties | 2 ++ 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index cf47f8aa6df..8cf4db093d8 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,10 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-docker-compose + @@ -118,11 +122,6 @@ spring-boot-testcontainers test - - org.springframework.boot - spring-boot-docker-compose - test - org.testcontainers junit-jupiter @@ -220,7 +219,7 @@ spring-boot-maven-plugin - build-info @@ -378,7 +377,7 @@ - org.eclipse.m2e @@ -436,4 +435,4 @@ - \ No newline at end of file + diff --git a/readme.md b/readme.md index 79b0fb692ae..0f57d9f5bbc 100644 --- a/readme.md +++ b/readme.md @@ -47,35 +47,23 @@ In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is exposed at `http://localhost:8080/h2-console`, and it is possible to inspect the content of the database using the `jdbc:h2:mem:` URL. The UUID is printed at startup to the console. -A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed. Note that whenever the database type changes, the app needs to run with a different profile: `spring.profiles.active=mysql` for MySQL or `spring.profiles.active=postgres` for PostgreSQL. +A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed using docker compose. -You can start MySQL or PostgreSQL locally with whatever installer works for your OS or use docker: +You only need to pass the Spring Boot profile at the time of running the application: ```bash -docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:8.2 +./mvnw spring-boot:run -Dspring-boot.run.profiles=mysql ``` or ```bash -docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 postgres:16.1 +./mvnw spring-boot:run -Dspring-boot.run.profiles=postgres ``` Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt) and [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt). -Instead of vanilla `docker` you can also use the provided `docker-compose.yml` file to start the database containers. Each one has a profile just like the Spring profile: - -```bash -docker-compose --profile mysql up -``` - -or - -```bash -docker-compose --profile postgres up -``` - ## Test Applications At development time we recommend you use the test applications set up as `main()` methods in `PetClinicIntegrationTests` (using the default H2 database and also adding Spring Boot Devtools), `MySqlTestApplication` and `PostgresIntegrationTests`. These are set up so that you can run the apps in your IDE to get fast feedback and also run the same classes as integration tests against the respective database. The MySql integration tests use Testcontainers to start the database in a Docker container, and the Postgres tests use Docker Compose to do the same thing. diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index e23dfa6055d..2b476bc66f0 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -5,3 +5,5 @@ spring.datasource.username=${MYSQL_USER:petclinic} spring.datasource.password=${MYSQL_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.sql.init.mode=always +# docker compose +spring.docker.compose.profiles.active=mysql diff --git a/src/main/resources/application-postgres.properties b/src/main/resources/application-postgres.properties index 60889b43c15..8a6cf45b23e 100644 --- a/src/main/resources/application-postgres.properties +++ b/src/main/resources/application-postgres.properties @@ -4,3 +4,5 @@ spring.datasource.username=${POSTGRES_USER:petclinic} spring.datasource.password=${POSTGRES_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.sql.init.mode=always +# docker compose +spring.docker.compose.profiles.active=postgres From 68dfdddd4dd88990e4202dc27f426014ef2b55c3 Mon Sep 17 00:00:00 2001 From: jmformenti Date: Sun, 17 Mar 2024 19:19:43 +0100 Subject: [PATCH 2/4] chore: Obsolete documentation removed --- readme.md | 3 -- .../db/mysql/petclinic_db_setup_mysql.txt | 36 ------------------- .../postgres/petclinic_db_setup_postgres.txt | 19 ---------- 3 files changed, 58 deletions(-) delete mode 100644 src/main/resources/db/mysql/petclinic_db_setup_mysql.txt delete mode 100644 src/main/resources/db/postgres/petclinic_db_setup_postgres.txt diff --git a/readme.md b/readme.md index 0f57d9f5bbc..03cfcf6361a 100644 --- a/readme.md +++ b/readme.md @@ -61,9 +61,6 @@ or ./mvnw spring-boot:run -Dspring-boot.run.profiles=postgres ``` -Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt) -and [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt). - ## Test Applications At development time we recommend you use the test applications set up as `main()` methods in `PetClinicIntegrationTests` (using the default H2 database and also adding Spring Boot Devtools), `MySqlTestApplication` and `PostgresIntegrationTests`. These are set up so that you can run the apps in your IDE to get fast feedback and also run the same classes as integration tests against the respective database. The MySql integration tests use Testcontainers to start the database in a Docker container, and the Postgres tests use Docker Compose to do the same thing. diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt deleted file mode 100644 index 8b39c07a40a..00000000000 --- a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt +++ /dev/null @@ -1,36 +0,0 @@ -================================================================================ -=== Spring PetClinic sample application - MySQL Configuration === -================================================================================ - -@author Sam Brannen -@author Costin Leau -@author Dave Syer - --------------------------------------------------------------------------------- - -1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), - which can be found here: https://dev.mysql.com/downloads/. Or run the - "docker-compose.yml" from the root of the project (if you have docker installed - locally): - - $ docker-compose up - ... - mysql_1_eedb4818d817 | MySQL init process done. Ready for start up. - ... - -2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql" - scripts. You can connect to the database running in the docker container using - `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there - because the petclinic user is already set up if you use the provided `docker-compose.yml`. - -3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command - line, but any way that sets that property in a Spring Boot app should work). For example use - - mvn spring-boot:run -Dspring-boot.run.profiles=mysql - - To activate the profile on the command line. - -N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value -as it is configured by default. This condition is taken care of automatically by the -docker-compose configuration provided, or by the `user.sql` script if you run that as -root. diff --git a/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt b/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt deleted file mode 100644 index a998749f0cc..00000000000 --- a/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt +++ /dev/null @@ -1,19 +0,0 @@ -=============================================================================== -=== Spring PetClinic sample application - PostgreSQL Configuration === -=============================================================================== - --------------------------------------------------------------------------------- - -1) Run the "docker-compose.yml" from the root of the project: - - $ docker-compose up - ... - spring-petclinic-postgres-1 | The files belonging to this database system will be owned by user "postgres". - ... - -2) Run the app with `spring.profiles.active=postgres` (e.g. as a System property via the command - line, but any way that sets that property in a Spring Boot app should work). For example use - - mvn spring-boot:run -Dspring-boot.run.profiles=postgres - - To activate the profile on the command line. From 5aedb473107d362c1107f7e22618aad5a1d6170d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josep=20Maria=20Forment=C3=AD=20Serra?= Date: Sat, 18 May 2024 14:16:50 +0200 Subject: [PATCH 3/4] chore: keep docker compose dependency with test scope. --- pom.xml | 15 ++++++++------- readme.md | 4 ++-- .../samples/petclinic/MysqlTestApplication.java | 17 ++++------------- .../petclinic/PostgresIntegrationTests.java | 3 --- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/pom.xml b/pom.xml index 8cf4db093d8..cf47f8aa6df 100644 --- a/pom.xml +++ b/pom.xml @@ -68,10 +68,6 @@ spring-boot-starter-test test - - org.springframework.boot - spring-boot-docker-compose - @@ -122,6 +118,11 @@ spring-boot-testcontainers test + + org.springframework.boot + spring-boot-docker-compose + test + org.testcontainers junit-jupiter @@ -219,7 +220,7 @@ spring-boot-maven-plugin - build-info @@ -377,7 +378,7 @@ - org.eclipse.m2e @@ -435,4 +436,4 @@ - + \ No newline at end of file diff --git a/readme.md b/readme.md index 03cfcf6361a..f290a416902 100644 --- a/readme.md +++ b/readme.md @@ -52,13 +52,13 @@ A similar setup is provided for MySQL and PostgreSQL if a persistent database co You only need to pass the Spring Boot profile at the time of running the application: ```bash -./mvnw spring-boot:run -Dspring-boot.run.profiles=mysql +./mvnw spring-boot:test-run -Dstart-class=org.springframework.samples.petclinic.MysqlTestApplication ``` or ```bash -./mvnw spring-boot:run -Dspring-boot.run.profiles=postgres +./mvnw spring-boot:test-run -Dstart-class=org.springframework.samples.petclinic.PostgresIntegrationTests ``` ## Test Applications diff --git a/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java b/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java index a3ee84bb01d..76adefa7534 100644 --- a/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java +++ b/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java @@ -16,12 +16,8 @@ package org.springframework.samples.petclinic; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.testcontainers.service.connection.ServiceConnection; -import org.springframework.context.annotation.Bean; +import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Profile; -import org.testcontainers.containers.MySQLContainer; /** * PetClinic Spring Boot Application. @@ -32,15 +28,10 @@ @Configuration public class MysqlTestApplication { - @ServiceConnection - @Profile("mysql") - @Bean - static MySQLContainer container() { - return new MySQLContainer<>("mysql:8.2"); - } - public static void main(String[] args) { - SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql"); + new SpringApplicationBuilder(PetClinicApplication.class) // + .profiles("mysql") // + .run(args); } } diff --git a/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java index 18945a57038..c4ca937c46b 100644 --- a/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java @@ -70,9 +70,6 @@ static void available() { public static void main(String[] args) { new SpringApplicationBuilder(PetClinicApplication.class) // .profiles("postgres") // - .properties( // - "spring.docker.compose.profiles.active=postgres" // - ) // .listeners(new PropertiesLogger()) // .run(args); } From a9bcd80b619f4130204dd1833d4f10d18549f355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josep=20Maria=20Forment=C3=AD=20Serra?= Date: Mon, 20 May 2024 08:15:39 +0200 Subject: [PATCH 4/4] chore: make it optional --- pom.xml | 30 ++++++++++++-- readme.md | 41 +++++++++++++++++-- .../application-docker-compose.properties | 1 + .../resources/application-mysql.properties | 2 - .../resources/application-postgres.properties | 2 - .../db/mysql/petclinic_db_setup_mysql.txt | 36 ++++++++++++++++ .../postgres/petclinic_db_setup_postgres.txt | 19 +++++++++ .../petclinic/MysqlTestApplication.java | 17 ++++++-- .../petclinic/PostgresIntegrationTests.java | 3 ++ 9 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/application-docker-compose.properties create mode 100644 src/main/resources/db/mysql/petclinic_db_setup_mysql.txt create mode 100644 src/main/resources/db/postgres/petclinic_db_setup_postgres.txt diff --git a/pom.xml b/pom.xml index cf47f8aa6df..383824385eb 100644 --- a/pom.xml +++ b/pom.xml @@ -220,7 +220,7 @@ spring-boot-maven-plugin - build-info @@ -378,7 +378,7 @@ - org.eclipse.m2e @@ -434,6 +434,30 @@ + + mysql + + mysql,docker-compose + + + + org.springframework.boot + spring-boot-docker-compose + + + + + postgres + + postgres,docker-compose + + + + org.springframework.boot + spring-boot-docker-compose + + + - \ No newline at end of file + diff --git a/readme.md b/readme.md index f290a416902..ee9817b0ff8 100644 --- a/readme.md +++ b/readme.md @@ -47,18 +47,51 @@ In its default configuration, Petclinic uses an in-memory database (H2) which gets populated at startup with data. The h2 console is exposed at `http://localhost:8080/h2-console`, and it is possible to inspect the content of the database using the `jdbc:h2:mem:` URL. The UUID is printed at startup to the console. -A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed using docker compose. +A similar setup is provided for MySQL and PostgreSQL if a persistent database configuration is needed. Two options are available: -You only need to pass the Spring Boot profile at the time of running the application: +### Enable database via maven profile + +Pass the profile for the corresponding database as an argument: + +```bash +./mvnw spring-boot:run -Pmysql +``` + +or + +```bash +./mvnw spring-boot:run -Ppostgres +``` + +### Manual configuration + +Note that whenever the database type changes, the app needs to run with a different profile: `spring.profiles.active=mysql` for MySQL or `spring.profiles.active=postgres` for PostgreSQL. + +You can start MySQL or PostgreSQL locally with whatever installer works for your OS or use docker: + +```bash +docker run -e MYSQL_USER=petclinic -e MYSQL_PASSWORD=petclinic -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=petclinic -p 3306:3306 mysql:8.2 +``` + +or + +```bash +docker run -e POSTGRES_USER=petclinic -e POSTGRES_PASSWORD=petclinic -e POSTGRES_DB=petclinic -p 5432:5432 postgres:16.1 +``` + +Further documentation is provided for [MySQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt) +and [PostgreSQL](https://github.com/spring-projects/spring-petclinic/blob/main/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt). + +Instead of vanilla `docker` you can also use the provided `docker-compose.yml` file to start the database containers. Each one has a profile just like the Spring profile: ```bash -./mvnw spring-boot:test-run -Dstart-class=org.springframework.samples.petclinic.MysqlTestApplication +docker-compose --profile mysql up ``` or ```bash -./mvnw spring-boot:test-run -Dstart-class=org.springframework.samples.petclinic.PostgresIntegrationTests +docker-compose --profile postgres up ``` ## Test Applications diff --git a/src/main/resources/application-docker-compose.properties b/src/main/resources/application-docker-compose.properties new file mode 100644 index 00000000000..6b3f6ae190f --- /dev/null +++ b/src/main/resources/application-docker-compose.properties @@ -0,0 +1 @@ +spring.docker.compose.profiles.active=${database} diff --git a/src/main/resources/application-mysql.properties b/src/main/resources/application-mysql.properties index 2b476bc66f0..e23dfa6055d 100644 --- a/src/main/resources/application-mysql.properties +++ b/src/main/resources/application-mysql.properties @@ -5,5 +5,3 @@ spring.datasource.username=${MYSQL_USER:petclinic} spring.datasource.password=${MYSQL_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.sql.init.mode=always -# docker compose -spring.docker.compose.profiles.active=mysql diff --git a/src/main/resources/application-postgres.properties b/src/main/resources/application-postgres.properties index 8a6cf45b23e..60889b43c15 100644 --- a/src/main/resources/application-postgres.properties +++ b/src/main/resources/application-postgres.properties @@ -4,5 +4,3 @@ spring.datasource.username=${POSTGRES_USER:petclinic} spring.datasource.password=${POSTGRES_PASS:petclinic} # SQL is written to be idempotent so this is safe spring.sql.init.mode=always -# docker compose -spring.docker.compose.profiles.active=postgres diff --git a/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt new file mode 100644 index 00000000000..8b39c07a40a --- /dev/null +++ b/src/main/resources/db/mysql/petclinic_db_setup_mysql.txt @@ -0,0 +1,36 @@ +================================================================================ +=== Spring PetClinic sample application - MySQL Configuration === +================================================================================ + +@author Sam Brannen +@author Costin Leau +@author Dave Syer + +-------------------------------------------------------------------------------- + +1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x), + which can be found here: https://dev.mysql.com/downloads/. Or run the + "docker-compose.yml" from the root of the project (if you have docker installed + locally): + + $ docker-compose up + ... + mysql_1_eedb4818d817 | MySQL init process done. Ready for start up. + ... + +2) (Once only) create the PetClinic database and user by executing the "db/mysql/user.sql" + scripts. You can connect to the database running in the docker container using + `mysql -u root -h localhost --protocol tcp`, but you don't need to run the script there + because the petclinic user is already set up if you use the provided `docker-compose.yml`. + +3) Run the app with `spring.profiles.active=mysql` (e.g. as a System property via the command + line, but any way that sets that property in a Spring Boot app should work). For example use + + mvn spring-boot:run -Dspring-boot.run.profiles=mysql + + To activate the profile on the command line. + +N.B. the "petclinic" database has to exist for the app to work with the JDBC URL value +as it is configured by default. This condition is taken care of automatically by the +docker-compose configuration provided, or by the `user.sql` script if you run that as +root. diff --git a/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt b/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt new file mode 100644 index 00000000000..a998749f0cc --- /dev/null +++ b/src/main/resources/db/postgres/petclinic_db_setup_postgres.txt @@ -0,0 +1,19 @@ +=============================================================================== +=== Spring PetClinic sample application - PostgreSQL Configuration === +=============================================================================== + +-------------------------------------------------------------------------------- + +1) Run the "docker-compose.yml" from the root of the project: + + $ docker-compose up + ... + spring-petclinic-postgres-1 | The files belonging to this database system will be owned by user "postgres". + ... + +2) Run the app with `spring.profiles.active=postgres` (e.g. as a System property via the command + line, but any way that sets that property in a Spring Boot app should work). For example use + + mvn spring-boot:run -Dspring-boot.run.profiles=postgres + + To activate the profile on the command line. diff --git a/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java b/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java index 76adefa7534..a3ee84bb01d 100644 --- a/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java +++ b/src/test/java/org/springframework/samples/petclinic/MysqlTestApplication.java @@ -16,8 +16,12 @@ package org.springframework.samples.petclinic; -import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.testcontainers.containers.MySQLContainer; /** * PetClinic Spring Boot Application. @@ -28,10 +32,15 @@ @Configuration public class MysqlTestApplication { + @ServiceConnection + @Profile("mysql") + @Bean + static MySQLContainer container() { + return new MySQLContainer<>("mysql:8.2"); + } + public static void main(String[] args) { - new SpringApplicationBuilder(PetClinicApplication.class) // - .profiles("mysql") // - .run(args); + SpringApplication.run(PetClinicApplication.class, "--spring.profiles.active=mysql"); } } diff --git a/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java b/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java index c4ca937c46b..18945a57038 100644 --- a/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java +++ b/src/test/java/org/springframework/samples/petclinic/PostgresIntegrationTests.java @@ -70,6 +70,9 @@ static void available() { public static void main(String[] args) { new SpringApplicationBuilder(PetClinicApplication.class) // .profiles("postgres") // + .properties( // + "spring.docker.compose.profiles.active=postgres" // + ) // .listeners(new PropertiesLogger()) // .run(args); }