diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f68528739..440de77c13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,12 @@ on GitHub. ## 3.4.0-SNAPSHOT +**This release officially introduces Spring Boot 2.7 compatibility.** +Note that the previous releases of Spring Cloud GCP 3.x are also compatible with Spring Boot 2.7. The one exception is that if you use Cloud SQL with R2DBC, you'd have to manage the driver versions in your own application dependencies (see [refdoc](https://github.com/GoogleCloudPlatform/spring-cloud-gcp/blob/main/docs/src/main/asciidoc/sql.adoc#r2dbc-support) for details). + +### Cloud SQL + - Add version management for the older MySQL and Postgres R2DBC drivers (https://github.com/GoogleCloudPlatform/spring-cloud-gcp/pull/1185). + ### Pub/Sub - Allow Publishers shutdown gracefully diff --git a/docs/src/main/asciidoc/sql.adoc b/docs/src/main/asciidoc/sql.adoc index 2f6d4d3746..489962d323 100644 --- a/docs/src/main/asciidoc/sql.adoc +++ b/docs/src/main/asciidoc/sql.adoc @@ -112,7 +112,7 @@ dependencies { } ---- -To use PostgreSQL: +To use PostgreSQL with Spring Boot 2.6: [source,xml] ---- @@ -129,6 +129,27 @@ dependencies { } ---- +To use PostgreSQL with Spring Boot 2.7 (the latest version of the Postgres R2DBC driver changed its Maven coordinates): + +``` xml + + com.google.cloud + spring-cloud-gcp-starter-sql-postgres-r2dbc + + + io.r2dbc + r2dbc-postgresql + + + + + + org.postgresql + r2dbc-postgresql + 0.9.1.RELEASE + +``` + ==== Prerequisites In order to use the Spring Boot Starters for Google Cloud SQL, the Google Cloud SQL API must be enabled in your GCP project. diff --git a/docs/src/main/md/sql.md b/docs/src/main/md/sql.md index 375496c4fc..0a5c973cf1 100644 --- a/docs/src/main/md/sql.md +++ b/docs/src/main/md/sql.md @@ -134,7 +134,7 @@ To use MySQL: implementation("com.google.cloud:spring-cloud-gcp-starter-sql-mysql-r2dbc") } -To use PostgreSQL: +To use PostgreSQL with Spring Boot 2.6: ``` xml @@ -147,6 +147,27 @@ To use PostgreSQL: implementation("com.google.cloud:spring-cloud-gcp-starter-sql-postgres-r2dbc") } +To use PostgreSQL with Spring Boot 2.7 (the latest version of the Postgres R2DBC driver changed its Maven coordinates): + +``` xml + + com.google.cloud + spring-cloud-gcp-starter-sql-postgres-r2dbc + + + io.r2dbc + r2dbc-postgresql + + + + + + org.postgresql + r2dbc-postgresql + 0.9.1.RELEASE + +``` + #### Prerequisites In order to use the Spring Boot Starters for Google Cloud SQL, the diff --git a/pom.xml b/pom.xml index 4aea3cb1f4..6b363c7380 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 2021.0.4 - 2.6.12 + 2.7.4 1.0.4 2.4.1 0.10.5 diff --git a/spring-cloud-gcp-autoconfigure/src/test/java/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessorTests.java b/spring-cloud-gcp-autoconfigure/src/test/java/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessorTests.java index f86e8d7404..44a34dbd76 100644 --- a/spring-cloud-gcp-autoconfigure/src/test/java/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessorTests.java +++ b/spring-cloud-gcp-autoconfigure/src/test/java/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessorTests.java @@ -18,6 +18,9 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import org.junit.jupiter.api.Test; import org.springframework.boot.SpringApplication; import org.springframework.boot.test.context.FilteredClassLoader; @@ -100,18 +103,48 @@ void testSetR2dbcProperty_mySql_urlProvidedByUserIgnored() { } @Test - void testSetR2dbcProperty_postgres_defaultUsername() { + void testSetR2dbcProperty_postgres() { + verifyThatCorrectUrlAndUsernameSet(new String[] {"io.r2dbc.postgresql"}, + "postgres", + "r2dbc:gcp:postgres://my-project:region:my-instance/my-database"); + } + + @Test + void testSetR2dbcProperty_mysql() { + verifyThatCorrectUrlAndUsernameSet(new String[] {"dev.miku.r2dbc.mysql"}, + "root", + "r2dbc:gcp:mysql://my-project:region:my-instance/my-database"); + } + + /** + * Verifies that correct database properties got injected into context, given a passed-in list of + * packages to retain on the classpath. + * + * @param driverPackagesToInclude a list of driver packages to keep on the classpath + * @param username expected {@code spring.r2dbc.username} value to verify + * @param url expected {@code spring.r2dbc.username} value to verify + */ + private void verifyThatCorrectUrlAndUsernameSet( + String[] driverPackagesToInclude, String username, String url) { + // Because `FilteredClassLoader` accepts a list of packages to remove from classpath, + // `driverPackagesToInclude` is used to calculate the inverse list of packages to _exclude_. + Set driverPackagesToExclude = new HashSet<>(Arrays.asList( + "dev.miku.r2dbc.mysql", + "io.r2dbc.postgresql" + )); + driverPackagesToExclude.removeAll(Arrays.asList(driverPackagesToInclude)); + this.contextRunner .withPropertyValues( "spring.cloud.gcp.sql.databaseName=my-database", "spring.cloud.gcp.sql.instanceConnectionName=my-project:region:my-instance") - .withClassLoader(new FilteredClassLoader("dev.miku.r2dbc.mysql")) + .withClassLoader(new FilteredClassLoader(driverPackagesToExclude.toArray(new String[0]))) .run( context -> { assertThat(context.getEnvironment().getProperty("spring.r2dbc.url")) - .isEqualTo("r2dbc:gcp:postgres://my-project:region:my-instance/my-database"); + .isEqualTo(url); assertThat(context.getEnvironment().getProperty("spring.r2dbc.username")) - .isEqualTo("postgres"); + .isEqualTo(username); }); } diff --git a/spring-cloud-gcp-dependencies/pom.xml b/spring-cloud-gcp-dependencies/pom.xml index 0844d09999..d861fe3c3f 100644 --- a/spring-cloud-gcp-dependencies/pom.xml +++ b/spring-cloud-gcp-dependencies/pom.xml @@ -32,6 +32,8 @@ 26.1.3 1.7.0 31.1-jre + 0.8.2.RELEASE + 0.8.12.RELEASE @@ -274,6 +276,16 @@ ${cloud-sql-socket-factory.version} + + + dev.miku + r2dbc-mysql + ${r2dbc-mysql-driver.version} + + com.google.cloud.sql @@ -281,6 +293,15 @@ ${cloud-sql-socket-factory.version} + + + io.r2dbc + r2dbc-postgresql + ${r2dbc-postgres-driver.version} + + com.google.cloud diff --git a/spring-cloud-gcp-samples/pom.xml b/spring-cloud-gcp-samples/pom.xml index 8bf0c1efa4..d88ea2008a 100644 --- a/spring-cloud-gcp-samples/pom.xml +++ b/spring-cloud-gcp-samples/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 2.6.12 + 2.7.4 diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample/src/main/resources/application.properties b/spring-cloud-gcp-samples/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample/src/main/resources/application.properties index 57c266075c..41478f72cd 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample/src/main/resources/application.properties +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-kotlin-samples/spring-cloud-gcp-kotlin-app-sample/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.cloud.gcp.sql.instance-connection-name=[YOUR_SQL_INSTANCE_NAME] # So app starts despite "table already exists" errors. spring.datasource.continue-on-error=true # Enforces database initialization -spring.datasource.initialization-mode=always +spring.sql.init.mode=always spring.jpa.hibernate.ddl-auto=create-drop diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample/src/main/resources/application.properties b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample/src/main/resources/application.properties index 44b0f19b47..8da27ea4ce 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample/src/main/resources/application.properties +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-sample/src/main/resources/application.properties @@ -4,7 +4,7 @@ spring.cloud.gcp.sql.instance-connection-name=[instance-connection-name] # So app starts despite "table already exists" errors. spring.datasource.continue-on-error=true # Enforces database initialization -spring.datasource.initialization-mode=always +spring.sql.init.mode=always # Leave empty for root, uncomment and fill out if you specified a user #spring.datasource.username= diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/main/resources/application.properties b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/main/resources/application.properties index 5fcc887eb0..4673f893a7 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/main/resources/application.properties +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/main/resources/application.properties @@ -7,6 +7,6 @@ spring.cloud.gcp.sql.instance-connection-name=[instance-connection-name] # So app starts despite "table already exists" errors. spring.datasource.continue-on-error=true # Enforces database initialization -spring.datasource.initialization-mode=always +spring.sql.init.mode=always #spring.cloud.gcp.project-id= #spring.cloud.gcp.credentials.location=file:/path/to/service-account.json diff --git a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/test/java/com/example/SqlPostgresSampleApplicationIntegrationTests.java b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/test/java/com/example/SqlPostgresSampleApplicationIntegrationTests.java index a29f3bef21..fe798c758c 100644 --- a/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/test/java/com/example/SqlPostgresSampleApplicationIntegrationTests.java +++ b/spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-sample/src/test/java/com/example/SqlPostgresSampleApplicationIntegrationTests.java @@ -46,7 +46,7 @@ "spring.datasource.username=postgres", "spring.datasource.password=test", "spring.datasource.continue-on-error=true", - "spring.datasource.initialization-mode=always" + "spring.sql.init.mode=always" }) class SqlPostgresSampleApplicationIntegrationTests {