Skip to content
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

feat: add support for rest-only services in generator #1849

Merged
merged 18 commits into from
Jun 12, 2023
Merged

Conversation

emmileaf
Copy link
Contributor

@emmileaf emmileaf commented May 15, 2023

Generator changes:

  • Removed exclusion for rest-only libraries in generate-library-list.sh
  • Removed exclusion for services with rest-only transport in SpringComposer
  • Added golden tests
  • In java-compute, newBuilder(), defaultTransportChannelProvider(), and defaultApiClientHeaderProviderBuilder() all default to REST implementation, so spring composer logic is kept the same as handling GRPC-only libraries: do not generate configurable useRest property, and use the default builders above in generated auto-configuration.

For reviewers:

  • Looking for a review on generator changes to include a starter module for compute (REST-only, GAPIC library): spring-cloud-previews/google-cloud-compute-spring-starter
  • Corresponding changes to generated code are now included this PR at 34495a0. (Previously in 213add0, #1850)
    • Added module google-cloud-compute-spring-starter
    • Across all generated modules: updated javadoc comment for TransportChannelProvider bean to reflect the current default behavior
    • Updated copyright year in license headers for auto-generated files (from upstream template change in gapic-generator-java

Memo on outstanding blocking changes:

Memo on non-blocking discussions / open follow-ups:

  • Alternative strategies for disabling/enabling autoconfiguration classes, and how these affect application start-up time (discussion)
  • Consider renaming and perhaps expanding configuration scope of the <service.prefix>.useRest property (discussion)
  • Workflow to push generated code changes introduced by generator changes as part of CI (discussion)

BEGIN_COMMIT_OVERRIDE

feat: add google-cloud-compute-spring-starter to starter modules available for preview

END_COMMIT_OVERRIDE

Copy link
Contributor

@blakeli0 blakeli0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In java-compute, newBuilder(), defaultTransportChannelProvider(), and defaultApiClientHeaderProviderBuilder() all default to REST implementation

This is good to know but also surprising, because it means if we change a REST only client to GRPC+REST, it would be a breaking change.

@blakeli0
Copy link
Contributor

Please see #1850 for showing of generated code corresponding to these changes

Not part of this PR, I wonder if it makes sense to regenerate the auto configs as part of the CI if we have changes in SpringCodeGen, so that we can see the changes directly in the same PR.

@emmileaf
Copy link
Contributor Author

Not part of this PR, I wonder if it makes sense to regenerate the auto configs as part of the CI if we have changes in SpringCodeGen, so that we can see the changes directly in the same PR.

@blakeli0 This suggestion actually makes me wonder - what would be the preferred timing to push any generated code changes introduced by changes to the generator? Currently I see the possibility for:

  1. As a commit added to the PR with generator changes (similar to your suggestion)
  2. As a separate PR along with (or after) merging the generator changes
  3. Not merged when introudcing generator changes, but will be included in the pre-release workflow in the PR to re-generate libraries as part of updating libraries-bom.

The status quo is 3, though this PR has been the first large generator feature change since initial release. Do we have any preference on what approach to take with this PR (which I will do manually), and which (if not the same) approach to follow in general? I think the possible CI/automation enhancements will look slightly different for each option.

@emmileaf emmileaf requested a review from blakeli0 May 19, 2023 16:34
if (hasRestOption) {
// For GRPC+REST libraries, provide configuration property to override GRPC default and use REST transport instead
// For GRPC-only and REST-only libraries, this property is not provided
if (ComposerUtils.shouldSupportRestOptionWithGrpcDefault(transport, service)) {
ExprStatement useRestVarStatement =
ComposerUtils.createMemberVarStatement(
"useRest",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered a transport property with an enum value of "REST" or "GRPC" instead? I feel that would be more natural than useRest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I can't recall if this was discussed when the useRest property was initially implemented, but two small complications I can see are:

  1. This would be a breaking change for any existing users of this property (though now would be the time if it's a change we'd like to eventually make)
  2. Possibly needing to document or account for case sensitivity in user-provided property strings? (e.g. REST vs. Rest)

If I'm understanding correctly, the user configuration to override would change from something like

<service.prefix>.useRest=true

to

<service.prefix>.transport=REST

This property is only exposed for libraries that support grpc+rest (and default to grpc), and having a property named useRest as an explicit override makes sense in my head as well, so I don't feel too strongly about either naming choice. Curious to hear any other concerns behind this suggestion though!

Copy link
Member

@meltsufin meltsufin May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're able to make this kind of change because we're still in preview. I believe that Spring Boot's relaxed binding should be case-insensitive for enums.
@blakeli0 Do you have an opinion on this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think explicitly specify<service.prefix>.transport=REST might be better in the long term, but there are more things we need to consider for this change.
For example, what would be the default value if this property is not specified? REST for compute and GRPC for the others? What's the criteria for us to decide the default value? What if a customer configured GRPC for compute, are we going to error out on start up?
In addition, are we going to support this property for existing spring-cloud-gcp products as well? Some of the service does not support REST yet or only support REST(bigquery), but I think some service like spanner already support both.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring Boot's relaxed binding should be case-insensitive for enums

Oh that’s good to know! I can give this change a try in a separate PR.

For example, what would be the default value if this property is not specified? REST for compute and GRPC for the others? What's the criteria for us to decide the default value? What if a customer configured GRPC for compute, are we going to error out on start up?

@blakeli0 My understanding of this suggested change is just in name/type (useRest boolean => transport enum) rather than the underlying behaviour: the current strategy is to only provide and support this property for libraries that support both GRPC+REST transport options. For GRPC and REST-only libraries where this property is not supported, any user configuration will not do anything (unless they override the transport provider and setting beans themselves), and the client library default builders will be used.

Would there be concern in this strategy itself, or is it more that having a renamed transport property only supported and applicable to some libraries could be confusing to users?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @blakeli0 brings up a good point about more things to consider. For instance, we can imagine a global spring.cloud.gcp.transport property that could switch all integrations to that transport. I almost feel like the property should be a list of desired transports. For instance, GRPC,REST would be the default and mean that choose REST only if GRPC is unavailable. Users, can still specify something like 'REST', which should fail with an unsupported-transport exception for libraries that only support GRPC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this is a relatively large topic that worth it's own discussion, can we leave it as it is for now? And put all the discussion around the naming together in a separate doc? We can always change it in preview but we should finalize it before GA.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure - I can put together a doc on this topic to further explore/discuss (similar to the other conversation on strategy to enable/disable configuration classes).

@blakeli0
Copy link
Contributor

Not part of this PR, I wonder if it makes sense to regenerate the auto configs as part of the CI if we have changes in SpringCodeGen, so that we can see the changes directly in the same PR.

@blakeli0 This suggestion actually makes me wonder - what would be the preferred timing to push any generated code changes introduced by changes to the generator? Currently I see the possibility for:

  1. As a commit added to the PR with generator changes (similar to your suggestion)
  2. As a separate PR along with (or after) merging the generator changes
  3. Not merged when introudcing generator changes, but will be included in the pre-release workflow in the PR to re-generate libraries as part of updating libraries-bom.

The status quo is 3, though this PR has been the first large generator feature change since initial release. Do we have any preference on what approach to take with this PR (which I will do manually), and which (if not the same) approach to follow in general? I think the possible CI/automation enhancements will look slightly different for each option.

We would always need 3 because the libraries bom could include new proto changes. In order for us to easily the generator changes, I think either 1 or 2 makes sense, otherwise all the generator changes and proto changes are in one huge PR before a new release. I would prefer 1 because it's easier to see all the generated changes in one PR, but 2 also has the advantage of seeing the generated changes separately so it's easier to review. This is not urgent, we can discuss it in next project meeting.

@emmileaf emmileaf closed this May 25, 2023
@emmileaf emmileaf reopened this May 25, 2023
@emmileaf
Copy link
Contributor Author

@blakeli0 @meltsufin Thanks for your patience in reviewing this! I’ve run the code generation workflow on this feature branch to now include the generated code changes as well, but please let me know if you have preferences on whether to merge these together or separately.

I think this PR is otherwise ready for a re-review at your convenience. Quick summary of three items from discussions above that I will follow-up on, separately from this PR:

  1. Alternative strategies for disabling/enabling autoconfiguration classes, and how these affect application start-up time (discussion)
  2. Consider renaming and perhaps expanding configuration scope of the <service.prefix>.useRest property (discussion)
  3. Workflow to push generated code changes introduced by generator changes as part of CI (discussion)

@@ -0,0 +1,223 @@
/*
* Copyright 2022 Google LLC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed the copyright year is still 2022, this is probably a bug in the generator though, similar to what I did last year. Can you take a look?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah this part is being handled by the gapic-generator-java composers; I've opened googleapis/sdk-platform-java#1720 for the corresponding fix. Thanks for catching!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

License headers (note: for all generated modules) updated in 34495a0.

@emmileaf emmileaf requested a review from a team as a code owner June 12, 2023 15:01
@emmileaf
Copy link
Contributor Author

Reverted changes to generated code, and retriggering to include generator updates above in https://github.com/GoogleCloudPlatform/spring-cloud-gcp/actions/runs/5245239436.

@emmileaf emmileaf closed this Jun 12, 2023
@emmileaf emmileaf reopened this Jun 12, 2023
@emmileaf emmileaf requested a review from blakeli0 June 12, 2023 15:33
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 6 Code Smells

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@emmileaf
Copy link
Contributor Author

Merging this in, with corresponding release note message (through commit override) as feat: add google-cloud-compute-spring-starter to starter modules available for preview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants