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

Add server RPC v2 CBOR support #2544

Merged
merged 87 commits into from
Jul 17, 2024
Merged

Add server RPC v2 CBOR support #2544

merged 87 commits into from
Jul 17, 2024

Conversation

david-perez
Copy link
Contributor

@david-perez david-perez commented Apr 4, 2023

RPC v2 CBOR is a new protocol that is being added has recently been added to the Smithy
specification.

(I'll add more details here as the patchset evolves)

Credit goes to @jjant for initial implementation of the router, which I built on top of from his jjant/smithy-rpc-v2-exploration branch.

Tracking issue: #3573.

Caveats

TODOs are currently exhaustively sprinkled throughout the patch documenting what remains to be done. Most of these need to be addressed before this can be merged in; some can be punted on to not make this PR bigger.

However, I'd like to call out the major caveats and blockers here. I'll keep updating this list as the patchset evolves.

  • RPC v2 has still not been added to the Smithy specification. It is currently being worked on over in the smithy-rpc-v2 branch. The following are prerrequisites for this PR to be merged; until they are done CI on this PR will fail:
  • Protocol tests for the protocol do not currently exist in Smithy. Until those get written, this PR resorts to Rust unit tests and integration tests that use serde to round-trip messages and compare serde's encoders and decoders with ours for correctness.
    • Protocol tests are under the smithy-protocol-tests directory in Smithy.
    • We're keeping the serde_cbor round-trip tests for defense in depth.
  • Add client support for RPC v2 CBOR protocol #3709 - Currently only server-side support has been implemented, because that's what I'm most familiar. However, we're almost all the way there to add client-side support.
  • [ ] Smithy document shapes are not supported. RPC v2's specification currently doesn't indicate how to implement them.
    • The spec ended up leaving them as unsupported: "Document types are not currently supported in this protocol."

Prerequisite PRs

This section lists prerequisite PRs and issues that would make the diff for this one lighter or easier to understand. It's preferable that these PRs be merged prior to this one; some are hard prerequisites. They mostly relate to parts of the codebase I've had to touch or pilfer inspect in this PR where I've made necessary changes, refactors and "drive-by improvements" that are mostly unrelated, although some directly unlock things I've needed in this patchset. It makes sense to pull them out to ease reviewability and make this patch more semantically self-contained.

Testing

RPC v2 has still not been added to the Smithy specification. It is currently being worked on over in the
smithy-rpc-v2 branch.

This can only be tested locally following these steps:

1. Clone the Smithy repository and checkout the smithy-rpc-v2 branch.
2. Inside your local checkout of smithy-rs pointing to this PR's branch, make sure you've added mavenLocal() as a repository in the build.gradle.kts files. Example.
4. Inside your local checkout of Smithy's smithy-rpc-v2 branch:
1. Set VERSION to the current Smithy version used in smithy-rs (1.28.1 as of writing, but check here).
2. Run ./gradlew clean build pTML.

6. 1. In your local checkout of the smithy-rs's smithy-rpc-v2 branch, run ./gradlew codegen-server-test:build -P modules='rpcv2Cbor'.

You can troubleshoot whether you have Smithy correctly set up locally by inspecting ~/.m2/repository/software/amazon/smithy/smithy-protocols-traits.

Checklist

  • I have updated CHANGELOG.next.toml if I made changes to the smithy-rs codegen or runtime crates

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@david-perez
Copy link
Contributor Author

david-perez commented Jun 4, 2024

Squashed all commits rebased on top of current origin/main and force-pushed to avoid runtime-versioner failure, which uses the previous release tag to be the ancestor tag release-2024-05-28 (because #3680 is not merged). It had no effect because CI is smart enough to download all tags before running the tool.

This fixes two bugs:

1. `Content-Type` header checking was succeeding when no `Content-Type`
   header was present but one was expected.
2. When a shape was @httpPayload`-bound, `Content-Type` header checking
   occurred even when no payload was being sent. In this case it is not
   necessary to check the header, since there is no content.

Code has been refactored and cleaned up. The crux of the logic is now
easier to understand, and contained in `content_type_header_classifier`.
…test model; but switching to refactoring protocol test generation now
@smithy-lang smithy-lang deleted a comment from github-actions bot Jul 10, 2024
@david-perez david-perez changed the title Add RPC v2 support Add server RPC v2 CBOR support Jul 10, 2024
@smithy-lang smithy-lang deleted a comment from github-actions bot Jul 10, 2024
@david-perez david-perez marked this pull request as ready for review July 10, 2024 16:27
@david-perez david-perez requested review from a team as code owners July 10, 2024 16:27
Copy link

Copy link
Contributor

@ysaito1001 ysaito1001 left a comment

Choose a reason for hiding this comment

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

Reviewed all but codegen-server-test, codegen/server, and aws-smithy-http-server. Thank you for @jjant for this awesome work!

* appear when serializing both.
*
* Strictly speaking, the spec says we should only add `__type` when serializing an operation error response, but
* there shouldn't™️ be any harm in always including it, which simplifies the code generator.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* there shouldn't™️ be any harm in always including it, which simplifies the code generator.
* there shouldn't be any harm in always including it, which simplifies the code generator.

Copy link

writable {
// We're only interested in _structure_ member shapes that can reach constrained shapes.
if (
codegenContext.model.expectShape(section.shape.container) is StructureShape &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, a Smithy shape is constrained, but somewhere in the codebase, we've already generated a Rust symbol that represents this fact. MaybeConstrained is a Rust type/symbol, not directly related to Smithy. My point is, we have 108 instances where we check if a Smithy shape is constrained. Instead, why don't we query the symbol provider or the symbol itself to determine if it supports the MaybeConstrained Rust type and if we need to issue a v.into() to convert to MaybeConstrained, rather than checking that a Shape's target can reach a constrained shape, and assuming we've generated a MaybeConstrained for that shape?

@david-perez david-perez enabled auto-merge July 17, 2024 09:23
Copy link

@david-perez david-perez added this pull request to the merge queue Jul 17, 2024
Merged via the queue into main with commit c63e792 Jul 17, 2024
43 of 44 checks passed
@david-perez david-perez deleted the smithy-rpc-v2 branch July 17, 2024 10:19
github-merge-queue bot pushed a commit that referenced this pull request Jul 31, 2024
## Motivation and Context
Follow-up on #2544 to add
client-side support for the protocol

## Description
The client implementation mainly focuses on a sub-section
[Requests](https://smithy.io/2.0/additional-specs/protocols/smithy-rpc-v2.html#requests)
in the spec. To that end, this PR addresses `TODO` for the client to
fill in the blanks and includes additional adjustments/refactoring to
pass client protocol tests.

## Testing
- Existing tests in CI
- Upstream protocol test `rpcv2Cbor`
- Our handwritten protocol test `rpcv2Cbor-extras.smithy`

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
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.

3 participants