-
Notifications
You must be signed in to change notification settings - Fork 23
Fix protocol initialization for AwsRestJson1Protocol #1023
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
Conversation
.../src/test/java/software/amazon/smithy/java/aws/server/restjson/AwsRestJson1ProtocolTest.java
Outdated
Show resolved
Hide resolved
...json/src/main/java/software/amazon/smithy/java/aws/server/restjson/AwsRestJson1Protocol.java
Outdated
Show resolved
Hide resolved
...rpcv2-cbor/src/test/java/software/amazon/smithy/java/server/rpcv2/RpcV2CborProtocolTest.java
Outdated
Show resolved
Hide resolved
...rpcv2-cbor/src/test/java/software/amazon/smithy/java/server/rpcv2/RpcV2CborProtocolTest.java
Outdated
Show resolved
Hide resolved
...rpcv2-cbor/src/test/java/software/amazon/smithy/java/server/rpcv2/RpcV2CborProtocolTest.java
Outdated
Show resolved
Hide resolved
.../src/test/java/software/amazon/smithy/java/aws/server/restjson/AwsRestJson1ProtocolTest.java
Outdated
Show resolved
Hide resolved
.../src/test/java/software/amazon/smithy/java/aws/server/restjson/AwsRestJson1ProtocolTest.java
Outdated
Show resolved
Hide resolved
.../src/test/java/software/amazon/smithy/java/aws/server/restjson/AwsRestJson1ProtocolTest.java
Outdated
Show resolved
Hide resolved
| var httpMethodToMatchers = new HashMap<String, UriMatcherMapBuilder<Operation<?, ?>>>(); | ||
| for (Service service : services) { | ||
| for (var operation : service.getAllOperations()) { | ||
| // Only process operations with HTTP trait. |
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.
With the RestJson protocol, all operations are required to have the HTTP trait, so this situation should not arise in the first place.
On that note, I don’t think this addresses the root cause of the problem, it only treats a symptom.
In my opinion, the correct fix is to make the protocol resolver filter and initialize only the providers that are actually required, based on the protocol traits declared on the service.
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's a fair callout. I looked into protocol-level filtering first but hit some blockers.
ProtocolResolver gets instantiated with the Server and supports multiple services simultaneously. Consider serviceA with restJson1 and rpcv2Cbor, and serviceB with only rpcv2Cbor. We'd still need handlers for both protocols loaded. Filtering at the constructor level wouldn't work for this case.
I tried implementing filtering anyway and ran into the TraitKey issue. ProtocolTestProtocolProvider provides a ShapeId but no trait class to construct a TraitKey from. Also not sure if protocol traits are even available in the schema at that point since some example services don't define protocols explicitly.
To unblock the issue and open up further discussion, and going through the options with Manuel, I decided to make HTTP_TRAIT retrieval defensive. This lets handlers instantiate even when services don't use restJson1 or have HTTP traits.
My understanding is that the server needs to be aware of all protocol handlers on the classpath to select the appropriate one at runtime. I think changing this pattern could be challenging, though I might be missing something.
In my opinion, the cleanest solution would be adding a filterCandidateServices method to ServerProtocolProvider. Each provider could implement its own filtering logic based on the wire protocol selection spec instead of failing during construction.
What do you think about that approach?
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.
Merging this and will continue the discussion offline.
…mithy/java/aws/server/restjson/AwsRestJson1Protocol.java Co-authored-by: Manuel Sugawara <sugmanue@amazon.com>
Issue #, if available:
Fixes #1017
Description of changes:
Root Cause:
When
AwsRestJson1Protocol(or other HTTP-based protocols) are present in the classpath, theProtocolResolverinstantiates them with all available services. The AwsRestJson1 protocol constructor iterates through all operations and callsexpectTrait(HTTP_TRAIT), which throws when operations don't have the HTTP trait. CBOR services won't have that trait.Changes
getTraitinstead ofexpectTraitwhich throws exception, and let it pass through.prioritytoprecisionto be consistent with description in Wire protocol selection docs.By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.