-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce EnvironmentPostProcessor for R2DBC support in Cloud Sql #772
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mostly commented just on the MySQL side as the comments equally apply to Postgres.
spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
...amples/spring-cloud-gcp-sql-mysql-r2dbc-sample/src/main/java/com/example/SqlApplication.java
Outdated
Show resolved
Hide resolved
...samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/src/main/java/com/example/WebController.java
Outdated
Show resolved
Hide resolved
spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/pom.xml
Outdated
Show resolved
Hide resolved
* | ||
*/ | ||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = { SqlApplication.class }, properties = { | ||
"spring.r2dbc.url=r2dbc:gcp:mysql://spring-cloud-gcp-ci:us-central1:testmysql/code_samples_r2dbc_db", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we put this configuration in under the spring-cloud-gcp-ci-it
profile like we did for the non-R2DBC sample?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The integration tests use different properties based on the database they're talking to. This might make it harder for them to be under the same profile? The non-R2DBC samples seem to use a hybrid approach where the mySQL test uses the profile while the postgreSQL test configures properties in the test. However, moving all the setup to the test classes could potentially help with readability. I could also be missing some maven-related knowledge here so let me know what you think.
spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
spring-cloud-gcp-samples/spring-cloud-gcp-sql-postgres-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
spring-cloud-gcp-starters/spring-cloud-gcp-starter-sql-r2dbc/pom.xml
Outdated
Show resolved
Hide resolved
...in/java/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessor.java
Show resolved
Hide resolved
...autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/sql/R2dbcDatabaseType.java
Outdated
Show resolved
Hide resolved
...cp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/src/main/resources/application.properties
Show resolved
Hide resolved
...rc/main/java/com/google/cloud/spring/autoconfigure/sql/CloudSqlEnvironmentPostProcessor.java
Outdated
Show resolved
Hide resolved
...autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/sql/R2dbcDatabaseType.java
Outdated
Show resolved
Hide resolved
@@ -52,8 +53,7 @@ | |||
* @author Eddú Meléndez | |||
*/ | |||
public class CloudSqlEnvironmentPostProcessor implements EnvironmentPostProcessor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seeing now how handling both JDBC and R2DBC in one class here is not really reusing that much code, and making it less readable, maybe a separate EventPostProcessor
is a better design after all. You can still re-use some code bt introducing a common AbstractCloudSqlEnvironmentPostProcessor
that both would extend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran into a self-created issue (provided wrong format for instance), but as part of troubleshooting noticed that Spring Data R2DBC configuration has a concept of ConnectionFactoryOptionsBuilderCustomizer
. This may be a more natural way to prepare options for the socket factory than the more generic environment post-processor. Could you try to replace R2dbcCloudSqlEnvironmentPostProcessor with a new autoconfiguration class? It will need to be listed in spring.factories under EnableAutoConfiguration
.
https://docs.spring.io/spring-boot/docs/2.5.7/reference/html/features.html#features.sql.r2dbc
...-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/sql/DatabaseType.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
DatabaseType getEnabledDatabaseType(ConfigurableEnvironment environment) { | ||
if (Boolean.parseBoolean(environment.getProperty("spring.cloud.gcp.sql.enabled", "true")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure that R2dbc post-processing is not triggered if the user just wants plain old JDBC>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. This method now returns null
if the dependency that is used to enable Spring R2DBC auto-configuration is not present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the user has the R2DBC dependency, but doesn't want our auto-configuration to kick in? I think we might need something like spring.cloud.gcp.sql.r2dbc.enabled
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be instead of spring.cloud.gcp.sql.enabled
for Cloud SQL R2DBC autoconfig being on, not in addition to, right?
I guess theoretically it's possible that an app wants spring.cloud.gcp.sql.enabled
for blocking connection to Cloud SQL, and then an R2DBC driver to another type of database. It would be weird for a reactive app to have blocking components, but not impossible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, spring.cloud.gcp.sql.enabled=false
would disable all of our Cloud SQL starters.
Maybe we need to add two properties: spring.cloud.gcp.sql.r2dbc.enabled
and spring.cloud.gcp.sql.jdbc.enabled
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for this PR, the check would be that both spring.cloud.gcp.sql.enabled
and spring.cloud.gcp.sql.r2dbc.enabled
are true. That sounds good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Also, consider introducing spring.cloud.gcp.sql.jdbc.enabled
.
Eventually, we might want to deprecate spring.cloud.gcp.sql.enabled
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is something that I did not think of before. Since it is possible for an app to expect a blocking connection while having the r2dbc driver on the classpath, introducing spring.cloud.gcp.sql.r2dbc.enabled
sounds like a good idea. I'll add spring.cloud.gcp.sql.jdbc.enabled
in a separate PR since it might break existing behavior for current cloud sql customers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@meltsufin @elefeint Added spring.cloud.gcp.sql.r2dbc.enabled
which will be true
by default.
...cp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/src/main/resources/application.properties
Show resolved
Hide resolved
spring-cloud-gcp-samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/README.adoc
Outdated
Show resolved
Hide resolved
That is a great discovery! I agree with you that If we want to only require the database name and the instance connection name to be provided without the need for the url (similar to what we have for the jdbc workflow) then the environment post processor will still be needed. Let me know what you think? |
@mpeddada1 That makes sense, thank you for checking! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, only a couple of minor changes.
...ava/com/google/cloud/spring/autoconfigure/sql/R2dbcCloudSqlEnvironmentPostProcessorTest.java
Outdated
Show resolved
Hide resolved
...samples/spring-cloud-gcp-sql-mysql-r2dbc-sample/src/main/java/com/example/WebController.java
Outdated
Show resolved
Hide resolved
...l-r2dbc-sample/src/test/java/com/example/SqlR2dbcMySqlSampleApplicationIntegrationTests.java
Outdated
Show resolved
Hide resolved
...ples/spring-cloud-gcp-sql-postgres-r2dbc-sample/src/main/java/com/example/WebController.java
Outdated
Show resolved
Hide resolved
...-gcp-autoconfigure/src/main/java/com/google/cloud/spring/autoconfigure/sql/DatabaseType.java
Outdated
Show resolved
Hide resolved
private static final Log LOGGER = LogFactory.getLog(R2dbcCloudSqlEnvironmentPostProcessor.class); | ||
|
||
@Override | ||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a minor thing, but I think there is even more code here that can be shared by adding some extra parameters to a helper method. It could make sense, unless it makes the code less readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm that's a good point. One potential area I can think of refactoring is CloudJdbcInfoProvider
and DefaultCloudSqlJdbcProvider
. We used this interface in the past because we also had AppEngineCloudSqlJdbcInfoProvider
but we may not need this interface anymore -- this can help reduce added hierarchy in the code. Additionally some of the code that is used to create a url can be shared between the r2dbc and jdbc workflow. I can do this refactoring in a follow-up PR if you think this is a good idea.
…p into autoconfigure-r2dbc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but note one comment on spring.cloud.gcp.sql.r2dbc.enabled
.
@elefeint WDYT?
...toconfigure/src/main/java/com/google/cloud/spring/autoconfigure/sql/PropertiesRetriever.java
Show resolved
Hide resolved
} | ||
|
||
DatabaseType getEnabledDatabaseType(ConfigurableEnvironment environment) { | ||
if (Boolean.parseBoolean(environment.getProperty("spring.cloud.gcp.sql.enabled", "true")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the user has the R2DBC dependency, but doesn't want our auto-configuration to kick in? I think we might need something like spring.cloud.gcp.sql.r2dbc.enabled
.
Kudos, SonarCloud Quality Gate passed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great.
Could you add a paragraph to refdoc in cloud-sql.adoc
? Can be a followup PR.
Thank you! Yup, I'll do this in a follow-up PR. |
This PR adds two starters for R2DBC support in Cloud SQL (one for mySQL and another for postgreSQL). It also includes 2 samples, associated integrations tests and documentation. The starters bring in spring-boot-starter-data-r2dbc which takes care of the creation of the ConnectionFactory bean.
…ogleCloudPlatform#772) This PR adds two starters for R2DBC support in Cloud SQL (one for mySQL and another for postgreSQL). It also includes 2 samples, associated integrations tests and documentation. The starters bring in spring-boot-starter-data-r2dbc which takes care of the creation of the ConnectionFactory bean.
Part 1 of #205
This PR adds two starters for R2DBC support in Cloud SQL (one for mySQL and another for postgreSQL). It also includes 2 samples, associated integrations tests and documentation. The starters bring in
spring-boot-starter-data-r2dbc
which takes care of the creation of theConnectionFactory
bean.Currently, authentication can only be done through the use of Application Default Credentials. The feature to pass credentials through
spring.cloud.gcp.credentials
orspring.cloud.gcp.sql.credentials
will be in the next PR(#775).